Search code examples
javagarbage-collectionbyte-buddy

What is the best way to trace who is calling System.gc


Is there a way to track down a System.gc caller without having to edit and recompile a class from the JDK? Something with Reflection (proxies) or with ByteBuddy? By the way, I'd need Java 8 and Java 17 ways (if they are different)

Note: I've come across these posts: How can I tell who calls System.gc()? and How do I replace Runtime.gc() with my own implementation? , but they suggest we should change some jdk code and recompile, well I think maybe there is a better way to do that.


Solution

  • The simplest way would be to attach a Java agent with a MemberSubstitution in Byte Buddy. You can use it to replace the call to System.gc to another static method that records the call instead of triggering the garbage collection, for example by writing down the stack trace.

    You'd use an AgentBuilder to create the agent and apply the substitution to all types and methods if you have no idea from where the call is coming.

    In theory, you could instrument the method itself but since it is native, it is not that straight forward, making the substitution the easiest option.