mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
refactor Vmtool, support singleton, support VMtoolMXBean. #1781
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package arthas;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* VMtool interface for JMX server. How to register VMtool MBean:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* ManagementFactory.getPlatformMBeanServer().registerMBean(
|
||||
* VMtool.getInstance(),
|
||||
* new ObjectName("arthas:type=VMtool")
|
||||
* );
|
||||
* }
|
||||
* </pre>
|
||||
* @author hengyunabc 2021-04-26
|
||||
*/
|
||||
public interface VMtoolMXBean {
|
||||
/**
|
||||
* 检测jni-lib是否正常,如果正常,应该输出OK
|
||||
*/
|
||||
public String check();
|
||||
|
||||
/**
|
||||
* 获取某个class在jvm中当前所有存活实例
|
||||
*/
|
||||
public <T> ArrayList<T> getInstances(Class<T> klass);
|
||||
|
||||
/**
|
||||
* 统计某个class在jvm中当前所有存活实例的总占用内存,单位:Byte
|
||||
*/
|
||||
public long sumInstanceSize(Class<?> klass);
|
||||
|
||||
/**
|
||||
* 获取某个实例的占用内存,单位:Byte
|
||||
*/
|
||||
public long getInstanceSize(Object instance);
|
||||
|
||||
/**
|
||||
* 统计某个class在jvm中当前所有存活实例的总个数
|
||||
*/
|
||||
public long countInstances(Class<?> klass);
|
||||
|
||||
/**
|
||||
* 获取所有已加载的类
|
||||
*/
|
||||
public ArrayList<Class<?>> getAllLoadedClasses();
|
||||
}
|
||||
@@ -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 <T> ArrayList<T> getInstances(Class<T> klass);
|
||||
private static native <T> ArrayList<T> getInstances0(Class<T> 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<Class<?>> getAllLoadedClasses();
|
||||
private static native ArrayList<Class<?>> getAllLoadedClasses0();
|
||||
|
||||
/**
|
||||
* 包括小类型(如int)
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public static ArrayList<Class> getAllClasses() {
|
||||
return getInstances(Class.class);
|
||||
return getInstances0(Class.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String check() {
|
||||
return check0();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ArrayList<T> getInstances(Class<T> 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<Class<?>> getAllLoadedClasses() {
|
||||
return getAllLoadedClasses0();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Class<?>> allLoadedClasses = Vmtool.getAllLoadedClasses();
|
||||
ArrayList<Class<?>> allLoadedClasses = vmtool.getAllLoadedClasses();
|
||||
System.out.println("allLoadedClasses->" + allLoadedClasses.size());
|
||||
|
||||
//通过下面的例子,可以看到getInstances(Class<T> klass)拿到的是当前存活的所有对象
|
||||
WeakReference<VmtoolTest> weakReference1 = new WeakReference<VmtoolTest>(new VmtoolTest());
|
||||
WeakReference<VmtoolTest> weakReference2 = new WeakReference<VmtoolTest>(new VmtoolTest());
|
||||
System.out.println(weakReference1.get() + " " + weakReference2.get());
|
||||
ArrayList<Vmtool> beforeInstances = Vmtool.getInstances(Vmtool.class);
|
||||
ArrayList<Vmtool> 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<Vmtool> afterInstances = Vmtool.getInstances(Vmtool.class);
|
||||
ArrayList<Vmtool> afterInstances = vmtool.getInstances(Vmtool.class);
|
||||
System.out.println("after instances->" + afterInstances);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
Reference in New Issue
Block a user