Skip to content

Instantly share code, notes, and snippets.

@shelajev
Last active January 10, 2020 08:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save shelajev/7c61cef769f4f98c823c to your computer and use it in GitHub Desktop.
Save shelajev/7c61cef769f4f98c823c to your computer and use it in GitHub Desktop.
IterateOverHeap JVMTI example
clang -shared -undefined dynamic_lookup -o agent.so -I /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/include/ -I /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/include/darwin native-agent.cpp
package org.shelajev;
public class Main {
public static void main(String[] args) {
System.out.println("Hello World!");
Thread t = new Thread();
int a = countInstances(Thread.class);
System.out.println("There are " + a + " instances of " + Thread.class);
}
private static native int countInstances(Class klass);
}
#include <jvmti.h>
#include <iostream>
using namespace std;
typedef struct {
jvmtiEnv *jvmti;
} GlobalAgentData;
static GlobalAgentData *gdata;
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
{
jvmtiEnv *jvmti = NULL;
jvmtiCapabilities capa;
jvmtiError error;
jint result = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
if (result != JNI_OK) {
printf("ERROR: Unable to access JVMTI!\n");
}
(void)memset(&capa, 0, sizeof(jvmtiCapabilities));
capa.can_tag_objects = 1;
error = (jvmti)->AddCapabilities(&capa);
gdata = (GlobalAgentData*) malloc(sizeof(GlobalAgentData));
gdata->jvmti = jvmti;
return JNI_OK;
}
extern "C"
JNICALL jint objectCountingCallback(jlong class_tag, jlong size, jlong* tag_ptr, jint length, void* user_data)
{
int* count = (int*) user_data;
*count += 1;
return JVMTI_VISIT_OBJECTS;
}
extern "C"
JNIEXPORT jint JNICALL Java_org_shelajev_Main_countInstances(JNIEnv *env, jclass thisClass, jclass klass)
{
int count = 0;
jvmtiHeapCallbacks callbacks;
(void)memset(&callbacks, 0, sizeof(callbacks));
callbacks.heap_iteration_callback = &objectCountingCallback;
jvmtiError error = gdata->jvmti->IterateThroughHeap(0, klass, &callbacks, &count);
return count;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment