Description
Frequently creating Fury instance lead to FGC
During encode
and decode
, fury.setCassloader
and fury.clearClassloader
are called before and after the actual serialization part; threadLocalFury are applied as default, arising following problems:
ThreadLocalFury introduce at least one fury instance for one thread
Now SOFARPC use ThreadLocalFury
, will maintain at least one Fury instance for each thread. Which already introduce large amount of Fury instances
while the amount of threads getting larger. (And notice that for each fury instance, its own class resolver, which usually become large object in heap, will be created.) Within this scope, ThreadLocalFury
might not be that appropriate for the situation.
New Fury instance created after clearClassLoader
is called
The clearClassLoader
will clear bindingThreadLocal.furyInstance
and give birth to instantiating of new Fury instance. This mechanism aggravate the abundance of fury instances in heap and increasing the likelihood of full GC.
Expected behavior
Growth rate of fury instances should be controllable.
Actual behavior
In our case, 20000 tps introduce 4581 fury instances. (For same situation, hessian could bears for 90 k tps)
Steps to reproduce
Simple benchmark on fury-sofarpc call.
Minimal yet complete reproducer code (or GitHub URL to code)
{
ServerConfig serverConfig;
ProviderConfig<UserService> providerConfig;
serverConfig = new ServerConfig()
.setProtocol("bolt")
.setPort(Integer.parseInt(port))
.setCoreThreads(1000)
.setMaxThreads(2000);
providerConfig = new ProviderConfig<UserService>()
.setInterfaceId(UserService.class.getName())
.setRef(new UserServiceServerImpl())
.setServer(serverConfig);
providerConfig.export();
}
{
ConsumerConfig<UserService> consumerConfig = new ConsumerConfig<UserService>()
.setRepeatedReferLimit(10)
.setInterfaceId(UserService.class.getName())
.setProtocol("bolt")
.setParameter("tr.protocol.default", "bolt")
.setDirectUrl("bolt://127.0.0.1:" + 12200).setConnectionNum(2000).setTimeout(10000);
consumerConfig.setSerialization("fury2");
UserService userService = consumerConfig.refer();
userService.existUser("dasd");
}
Environment
- SOFARPC version: 5.13.0
- JVM version (e.g.
java -version
): 8u291, whatever - OS version (e.g.
uname -a
): Darwin Kernel Version 20.6.0, whatever - Maven version: 3.6.1