This is a native JVMTI agent for a JVM, which is currently used in the IDEA debugger to perform basic heap diagnostic during the debug process. It can also be used in any project, that is running on a JVM, to attach allocation sampling listeners for low-overhead heap profiling and to collect information about the heap, such as retained sizes, object reachability, and paths to closest GC roots.
Using the memory agent, you can attach allocation listeners that will catch allocation sampling events and execute your code. In the example below a stack trace of each allocation is printed.
MemoryAgent agent = MemoryAgent.get();
agent.addAllocationListener((info) -> {
for (StackTraceElement element : info.getThread().getStackTrace()) {
System.out.println(element);
}
});
You can also change the heap sampling interval with
agent.setHeapSamplingInterval(512);
The overhead for allocation sampling is 1-3% if the user-defined code is not taken into account.
The example below shows how to check object reachability in the heap with weak/soft/phantom reference handling.
MemoryAgent agent = MemoryAgent.get();
// Passing null here forces the agent to traverse heap from the GC roots
System.out.println(agent.getFirstReachableObject(null, TestClass.class));
for (TestClass instance : agent.getAllReachableObjects(null, TestClass.class)) {
System.out.println(instance);
}
The library is published to the bintray repository.
Add the external repository url:
<repositories>
<repository>
<id>jetbrains.bintray</id>
<url>https://jetbrains.bintray.com/intellij-third-party-dependencies</url>
</repository>
</repositories>
Then add the dependency:
<dependencies>
<dependency>
<groupId>org.jetbrains.intellij.deps</groupId>
<artifactId>debugger-memory-agent</artifactId>
<version>1.0.32</version>
</dependency>
</dependencies>
Add the external repository url:
repositories {
maven {
url "https://jetbrains.bintray.com/intellij-third-party-dependencies"
}
}
Then add the dependency:
dependencies {
implementation 'org.jetbrains.intellij.deps:debugger-memory-agent:1.0.32'
}
Add the external repository url:
repositories {
maven {
url = uri("https://jetbrains.bintray.com/intellij-third-party-dependencies")
}
}
Then add the dependency:
dependencies {
implementation("org.jetbrains.intellij.deps:debugger-memory-agent:1.0.32")
}
If the agent library doesn't meet your needs, you can still attach the agent to a JVM separately. To do so, you should compile the agent library following the steps in CONTRIBUTING.md. Then run a JVM with the parameter:
-agentpath:/path/to/agent/library
.
After that, you can call the memory agent's methods using the IdeaNativeAgentProxy class.
See CONTRIBUTING.md for building and development tips before submitting a pull request. File an issue if you find any bug or have an idea for a new feature.