Skip to content

Frequently creating Fury instances, leading to FGC #1424

Open
@Lo1nt

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

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglaterThis will be worked on in later version

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions