diff --git a/arthas-vmtool/src/main/java/arthas/VMtoolMXBean.java b/arthas-vmtool/src/main/java/arthas/VMtoolMXBean.java
new file mode 100644
index 000000000..537a081a0
--- /dev/null
+++ b/arthas-vmtool/src/main/java/arthas/VMtoolMXBean.java
@@ -0,0 +1,48 @@
+package arthas;
+
+import java.util.ArrayList;
+
+/**
+ * VMtool interface for JMX server. How to register VMtool MBean:
+ *
+ *
+ * {@code
+ * ManagementFactory.getPlatformMBeanServer().registerMBean(
+ * VMtool.getInstance(),
+ * new ObjectName("arthas:type=VMtool")
+ * );
+ * }
+ *
+ * @author hengyunabc 2021-04-26
+ */
+public interface VMtoolMXBean {
+ /**
+ * 检测jni-lib是否正常,如果正常,应该输出OK
+ */
+ public String check();
+
+ /**
+ * 获取某个class在jvm中当前所有存活实例
+ */
+ public ArrayList getInstances(Class klass);
+
+ /**
+ * 统计某个class在jvm中当前所有存活实例的总占用内存,单位:Byte
+ */
+ public long sumInstanceSize(Class> klass);
+
+ /**
+ * 获取某个实例的占用内存,单位:Byte
+ */
+ public long getInstanceSize(Object instance);
+
+ /**
+ * 统计某个class在jvm中当前所有存活实例的总个数
+ */
+ public long countInstances(Class> klass);
+
+ /**
+ * 获取所有已加载的类
+ */
+ public ArrayList> getAllLoadedClasses();
+}
diff --git a/arthas-vmtool/src/main/java/arthas/Vmtool.java b/arthas-vmtool/src/main/java/arthas/Vmtool.java
index 3430ae95b..1f0c21ab3 100644
--- a/arthas-vmtool/src/main/java/arthas/Vmtool.java
+++ b/arthas-vmtool/src/main/java/arthas/Vmtool.java
@@ -7,7 +7,7 @@ import java.util.ArrayList;
* @author hengyunabc 2021-04-26
* @since 3.5.1
*/
-public class Vmtool {
+public class Vmtool implements VMtoolMXBean {
/**
* 不要修改jni-lib的名称
@@ -41,39 +41,69 @@ public class Vmtool {
/**
* 检测jni-lib是否正常,如果正常,应该输出OK
*/
- public static native String check();
+ private static native String check0();
/**
* 获取某个class在jvm中当前所有存活实例
*/
- public static native ArrayList getInstances(Class klass);
+ private static native ArrayList getInstances0(Class klass);
/**
* 统计某个class在jvm中当前所有存活实例的总占用内存,单位:Byte
*/
- public static native long sumInstanceSize(Class> klass);
+ private static native long sumInstanceSize0(Class> klass);
/**
* 获取某个实例的占用内存,单位:Byte
*/
- public static native long getInstanceSize(Object instance);
+ private static native long getInstanceSize0(Object instance);
/**
* 统计某个class在jvm中当前所有存活实例的总个数
*/
- public static native long countInstances(Class> klass);
+ private static native long countInstances0(Class> klass);
/**
* 获取所有已加载的类
*/
- public static native ArrayList> getAllLoadedClasses();
+ private static native ArrayList> getAllLoadedClasses0();
/**
* 包括小类型(如int)
*/
@SuppressWarnings("all")
public static ArrayList getAllClasses() {
- return getInstances(Class.class);
+ return getInstances0(Class.class);
+ }
+
+ @Override
+ public String check() {
+ return check0();
+ }
+
+ @Override
+ public ArrayList getInstances(Class klass) {
+ return getInstances0(klass);
+ }
+
+ @Override
+ public long sumInstanceSize(Class> klass) {
+ return sumInstanceSize0(klass);
+ }
+
+ @Override
+ public long getInstanceSize(Object instance) {
+ return getInstanceSize0(instance);
+ }
+
+ @Override
+ public long countInstances(Class> klass) {
+ return countInstances0(klass);
+ }
+
+ @Override
+ public ArrayList> getAllLoadedClasses() {
+ return getAllLoadedClasses0();
}
}
diff --git a/arthas-vmtool/src/main/native/include/arthas_Vmtool.h b/arthas-vmtool/src/main/native/include/arthas_Vmtool.h
index 903c47405..2d03330c5 100644
--- a/arthas-vmtool/src/main/native/include/arthas_Vmtool.h
+++ b/arthas-vmtool/src/main/native/include/arthas_Vmtool.h
@@ -12,7 +12,7 @@ extern "C" {
* Method: check
* Signature: ()Ljava/lang/String;
*/
-JNIEXPORT jstring JNICALL Java_arthas_Vmtool_check
+JNIEXPORT jstring JNICALL Java_arthas_Vmtool_check0
(JNIEnv *, jclass);
/*
diff --git a/arthas-vmtool/src/main/native/src/jni-library.cpp b/arthas-vmtool/src/main/native/src/jni-library.cpp
index 2e81b183c..d140541a5 100644
--- a/arthas-vmtool/src/main/native/src/jni-library.cpp
+++ b/arthas-vmtool/src/main/native/src/jni-library.cpp
@@ -6,7 +6,7 @@
extern "C"
JNIEXPORT jstring JNICALL
-Java_arthas_Vmtool_check(JNIEnv *env, jclass thisClass) {
+Java_arthas_Vmtool_check0(JNIEnv *env, jclass thisClass) {
return env->NewStringUTF("OK");
}
@@ -47,7 +47,7 @@ HeapObjectCallback(jlong class_tag, jlong size, jlong *tag_ptr, void *user_data)
extern "C"
JNIEXPORT jobject JNICALL
-Java_arthas_Vmtool_getInstances(JNIEnv *env, jclass thisClass, jclass klass) {
+Java_arthas_Vmtool_getInstances0(JNIEnv *env, jclass thisClass, jclass klass) {
jvmtiEnv *jvmti = getJvmtiEnv(env);
@@ -88,7 +88,7 @@ Java_arthas_Vmtool_getInstances(JNIEnv *env, jclass thisClass, jclass klass) {
extern "C"
JNIEXPORT jlong JNICALL
-Java_arthas_Vmtool_sumInstanceSize(JNIEnv *env, jclass thisClass, jclass klass) {
+Java_arthas_Vmtool_sumInstanceSize0(JNIEnv *env, jclass thisClass, jclass klass) {
jvmtiEnv *jvmti = getJvmtiEnv(env);
@@ -126,7 +126,7 @@ Java_arthas_Vmtool_sumInstanceSize(JNIEnv *env, jclass thisClass, jclass klass)
}
extern "C"
-JNIEXPORT jlong JNICALL Java_arthas_Vmtool_getInstanceSize
+JNIEXPORT jlong JNICALL Java_arthas_Vmtool_getInstanceSize0
(JNIEnv *env, jclass thisClass, jobject instance) {
jvmtiEnv *jvmti = getJvmtiEnv(env);
@@ -142,7 +142,7 @@ JNIEXPORT jlong JNICALL Java_arthas_Vmtool_getInstanceSize
extern "C"
JNIEXPORT jlong JNICALL
-Java_arthas_Vmtool_countInstances(JNIEnv *env, jclass thisClass, jclass klass) {
+Java_arthas_Vmtool_countInstances0(JNIEnv *env, jclass thisClass, jclass klass) {
jvmtiEnv *jvmti = getJvmtiEnv(env);
@@ -172,7 +172,7 @@ Java_arthas_Vmtool_countInstances(JNIEnv *env, jclass thisClass, jclass klass) {
}
extern "C"
-JNIEXPORT jobject JNICALL Java_arthas_Vmtool_getAllLoadedClasses
+JNIEXPORT jobject JNICALL Java_arthas_Vmtool_getAllLoadedClasses0
(JNIEnv *env, jclass thisClass) {
jvmtiEnv *jvmti = getJvmtiEnv(env);
diff --git a/arthas-vmtool/src/test/java/arthas/VmtoolTest.java b/arthas-vmtool/src/test/java/arthas/VmtoolTest.java
index 915e0d54b..fe1592557 100644
--- a/arthas-vmtool/src/test/java/arthas/VmtoolTest.java
+++ b/arthas-vmtool/src/test/java/arthas/VmtoolTest.java
@@ -28,27 +28,27 @@ public class VmtoolTest {
System.err.println(path);
String libPath = new File(path, System.mapLibraryName(Vmtool.JNI_LIBRARY_NAME)).getAbsolutePath();
- Vmtool.getInstance(libPath);
+ Vmtool vmtool = Vmtool.getInstance(libPath);
//调用native方法,获取已加载的类,不包括小类型(如int)
- ArrayList> allLoadedClasses = Vmtool.getAllLoadedClasses();
+ ArrayList> allLoadedClasses = vmtool.getAllLoadedClasses();
System.out.println("allLoadedClasses->" + allLoadedClasses.size());
//通过下面的例子,可以看到getInstances(Class klass)拿到的是当前存活的所有对象
WeakReference weakReference1 = new WeakReference(new VmtoolTest());
WeakReference weakReference2 = new WeakReference(new VmtoolTest());
System.out.println(weakReference1.get() + " " + weakReference2.get());
- ArrayList beforeInstances = Vmtool.getInstances(Vmtool.class);
+ ArrayList beforeInstances = vmtool.getInstances(Vmtool.class);
System.out.println("before instances->" + beforeInstances);
- System.out.println("size->" + Vmtool.getInstanceSize(weakReference1.get()));
- System.out.println("count->" + Vmtool.countInstances(Vmtool.class));
- System.out.println("sum size->" + Vmtool.sumInstanceSize(Vmtool.class));
+ System.out.println("size->" + vmtool.getInstanceSize(weakReference1.get()));
+ System.out.println("count->" + vmtool.countInstances(Vmtool.class));
+ System.out.println("sum size->" + vmtool.sumInstanceSize(Vmtool.class));
beforeInstances = null;
System.gc();
Thread.sleep(100);
System.out.println(weakReference1.get() + " " + weakReference2.get());
- ArrayList afterInstances = Vmtool.getInstances(Vmtool.class);
+ ArrayList afterInstances = vmtool.getInstances(Vmtool.class);
System.out.println("after instances->" + afterInstances);
} catch (Exception e) {
e.printStackTrace();