From e2e7061182c5bcad7699e5bfb5f9f217fe0732ee Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Fri, 7 May 2021 22:49:04 +0800 Subject: [PATCH] vmtool support limit option. #1781 --- .../src/main/java/arthas/VmTool.java | 14 +++++-- .../src/main/java/arthas/VmToolMXBean.java | 8 +++- .../src/main/native/src/jni-library.cpp | 37 +++++++++++++++++- .../src/test/java/arthas/VmToolTest.java | 22 +++++++++++ .../command/monitor200/VmToolCommand.java | 16 +++++++- lib/libArthasJniLibrary-x64.dylib | Bin 53248 -> 52440 bytes spy/src/main/java/arthas/VmTool.java | 36 ++++++++--------- spy/src/main/java/arthas/VmToolMXBean.java | 12 +++--- 8 files changed, 114 insertions(+), 31 deletions(-) diff --git a/arthas-vmtool/src/main/java/arthas/VmTool.java b/arthas-vmtool/src/main/java/arthas/VmTool.java index a54974ba4..4e2775648 100644 --- a/arthas-vmtool/src/main/java/arthas/VmTool.java +++ b/arthas-vmtool/src/main/java/arthas/VmTool.java @@ -46,12 +46,12 @@ public class VmTool implements VmToolMXBean { /** * 获取某个class在jvm中当前所有存活实例 */ - private static synchronized native T[] getInstances0(Class klass); + private static synchronized native T[] getInstances0(Class klass, int limit); /** * 统计某个class在jvm中当前所有存活实例的总占用内存,单位:Byte */ - private static native long sumInstanceSize0(Class klass); + private static synchronized native long sumInstanceSize0(Class klass); /** * 获取某个实例的占用内存,单位:Byte @@ -77,7 +77,15 @@ public class VmTool implements VmToolMXBean { @Override public T[] getInstances(Class klass) { - return getInstances0(klass); + return getInstances0(klass, -1); + } + + @Override + public T[] getInstances(Class klass, int limit) { + if (limit == 0) { + throw new IllegalArgumentException("limit can not be 0"); + } + return getInstances0(klass, limit); } @Override diff --git a/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java b/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java index d1a18ab87..f21000115 100644 --- a/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java +++ b/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java @@ -20,10 +20,16 @@ public interface VmToolMXBean { */ public void forceGc(); + public T[] getInstances(Class klass); + /** * 获取某个class在jvm中当前所有存活实例 + * @param + * @param klass + * @param limit 如果小于 0 ,则不限制 + * @return */ - public T[] getInstances(Class klass); + public T[] getInstances(Class klass, int limit); /** * 统计某个class在jvm中当前所有存活实例的总占用内存,单位:Byte diff --git a/arthas-vmtool/src/main/native/src/jni-library.cpp b/arthas-vmtool/src/main/native/src/jni-library.cpp index d1dd5d430..c0bbc33ad 100644 --- a/arthas-vmtool/src/main/native/src/jni-library.cpp +++ b/arthas-vmtool/src/main/native/src/jni-library.cpp @@ -8,6 +8,30 @@ static jvmtiEnv *jvmti; static jlong tagCounter = 0; +struct LimitCounter { + jint currentCounter; + jint limitValue; + + void init(jint limit) { + currentCounter = 0; + limitValue = limit; + } + + void countDown() { + currentCounter++; + } + + bool allow() { + if (limitValue < 0) { + return true; + } + return limitValue > currentCounter; + } +}; + +// 每次 IterateOverInstancesOfClass 调用前需要先 init +static LimitCounter limitCounter = {0, 0}; + extern "C" int init_agent(JavaVM *vm, void *reserved) { jint rc; @@ -61,13 +85,20 @@ jvmtiIterationControl JNICALL HeapObjectCallback(jlong class_tag, jlong size, jlong *tag_ptr, void *user_data) { jlong *data = static_cast(user_data); *tag_ptr = *data; - return JVMTI_ITERATION_CONTINUE; + + limitCounter.countDown(); + if (limitCounter.allow()) { + return JVMTI_ITERATION_CONTINUE; + }else { + return JVMTI_ITERATION_ABORT; + } } extern "C" JNIEXPORT jobjectArray JNICALL -Java_arthas_VmTool_getInstances0(JNIEnv *env, jclass thisClass, jclass klass) { +Java_arthas_VmTool_getInstances0(JNIEnv *env, jclass thisClass, jclass klass, jint limit) { jlong tag = getTag(); + limitCounter.init(limit); jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER, HeapObjectCallback, &tag); if (error) { @@ -96,6 +127,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_arthas_VmTool_sumInstanceSize0(JNIEnv *env, jclass thisClass, jclass klass) { jlong tag = getTag(); + limitCounter.init(-1); jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER, HeapObjectCallback, &tag); if (error) { @@ -136,6 +168,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_arthas_VmTool_countInstances0(JNIEnv *env, jclass thisClass, jclass klass) { jlong tag = getTag(); + limitCounter.init(-1); jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER, HeapObjectCallback, &tag); if (error) { diff --git a/arthas-vmtool/src/test/java/arthas/VmToolTest.java b/arthas-vmtool/src/test/java/arthas/VmToolTest.java index 7cdc2f049..3cc02f691 100644 --- a/arthas-vmtool/src/test/java/arthas/VmToolTest.java +++ b/arthas-vmtool/src/test/java/arthas/VmToolTest.java @@ -2,6 +2,7 @@ package arthas; import java.io.File; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.concurrent.atomic.AtomicLong; import org.assertj.core.api.Assertions; @@ -9,6 +10,8 @@ import org.junit.Test; import com.taobao.arthas.common.VmToolUtils; +import arthas.VmToolTest.LimitTest; + /** * 以下本地测试的jvm参数均为:-Xms128m -Xmx128m */ @@ -146,6 +149,25 @@ public class VmToolTest { } } + class LimitTest { + } + + @Test + public void test_getInstances_lmiit() { + VmTool vmtool = initVmTool(); + + ArrayList list = new ArrayList(); + for (int i = 0; i < 10; ++i) { + list.add(new LimitTest()); + } + LimitTest[] instances = vmtool.getInstances(LimitTest.class, 5); + Assertions.assertThat(instances).hasSize(5); + LimitTest[] instances2 = vmtool.getInstances(LimitTest.class, -1); + Assertions.assertThat(instances2).hasSize(10); + LimitTest[] instances3 = vmtool.getInstances(LimitTest.class, 1); + Assertions.assertThat(instances3).hasSize(1); + } + interface III { } diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java index 05ab8cd12..e053b59f6 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java @@ -47,6 +47,8 @@ import arthas.VmTool; @Description(Constants.EXAMPLE + " vmtool --action getInstances --className demo.MathGame\n" + " vmtool --action getInstances --className demo.MathGame --express 'instances.length'\n" + + " vmtool --action getInstances --className demo.MathGame --express 'instances[0]'\n" + + " vmtool --action getInstances --className java.lang.String --limit 10\n" + " vmtool --action forceGc\n" + Constants.WIKI + Constants.WIKI_HOME + "vmtool") //@formatter:on @@ -64,6 +66,11 @@ public class VmToolCommand extends AnnotatedCommand { */ private int expand; + /** + * default value 10 + */ + private int limit; + private static String libPath; private static VmTool vmTool = null; @@ -117,6 +124,13 @@ public class VmToolCommand extends AnnotatedCommand { this.classLoaderClass = classLoaderClass; } + @Option(shortName = "l", longName = "limit") + @Description("Set the limit value of the getInstances action, default value is 10, set to -1 is unlimited") + @DefaultValue("10") + public void setLimit(int limit) { + this.limit = limit; + } + @Option(longName = "express", required = false) @Description("The ognl expression, default valueis `instances`.") public void setExpress(String express) { @@ -165,7 +179,7 @@ public class VmToolCommand extends AnnotatedCommand { process.end(-1, "Found more than one class: " + matchedClasses + "."); return; } else { - Object[] instances = vmToolInstance().getInstances(matchedClasses.get(0)); + Object[] instances = vmToolInstance().getInstances(matchedClasses.get(0), limit); Object value = instances; if (express != null) { Express unpooledExpress = ExpressFactory.unpooledExpress(classLoader); diff --git a/lib/libArthasJniLibrary-x64.dylib b/lib/libArthasJniLibrary-x64.dylib index 5547993f54f3f17dad8737f111553030136e765f..bf5f6ef13061928e18601c3bf688eb9310e22a10 100644 GIT binary patch literal 52440 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 literal 53248 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 diff --git a/spy/src/main/java/arthas/VmTool.java b/spy/src/main/java/arthas/VmTool.java index d530a06d5..4e2775648 100644 --- a/spy/src/main/java/arthas/VmTool.java +++ b/spy/src/main/java/arthas/VmTool.java @@ -41,17 +41,17 @@ public class VmTool implements VmToolMXBean { */ private static native String check0(); - private static native void forceGc0(); + private static synchronized native void forceGc0(); /** * 获取某个class在jvm中当前所有存活实例 */ - private static native T[] getInstances0(Class klass); + private static synchronized native T[] getInstances0(Class klass, int limit); /** * 统计某个class在jvm中当前所有存活实例的总占用内存,单位:Byte */ - private static native long sumInstanceSize0(Class klass); + private static synchronized native long sumInstanceSize0(Class klass); /** * 获取某个实例的占用内存,单位:Byte @@ -61,24 +61,14 @@ public class VmTool implements VmToolMXBean { /** * 统计某个class在jvm中当前所有存活实例的总个数 */ - private static native long countInstances0(Class klass); + private static synchronized native long countInstances0(Class klass); /** * 获取所有已加载的类 + * @param klass 这个参数必须是 Class.class + * @return */ - private static native Class[] getAllLoadedClasses0(); - - /** - * 包括小类型(如int) - */ - public static Class[] getAllClasses() { - return getInstances0(Class.class); - } - - @Override - public String check() { - return check0(); - } + private static synchronized native Class[] getAllLoadedClasses0(Class klass); @Override public void forceGc() { @@ -87,7 +77,15 @@ public class VmTool implements VmToolMXBean { @Override public T[] getInstances(Class klass) { - return getInstances0(klass); + return getInstances0(klass, -1); + } + + @Override + public T[] getInstances(Class klass, int limit) { + if (limit == 0) { + throw new IllegalArgumentException("limit can not be 0"); + } + return getInstances0(klass, limit); } @Override @@ -107,7 +105,7 @@ public class VmTool implements VmToolMXBean { @Override public Class[] getAllLoadedClasses() { - return getAllLoadedClasses0(); + return getAllLoadedClasses0(Class.class); } } diff --git a/spy/src/main/java/arthas/VmToolMXBean.java b/spy/src/main/java/arthas/VmToolMXBean.java index 92df09be1..f21000115 100644 --- a/spy/src/main/java/arthas/VmToolMXBean.java +++ b/spy/src/main/java/arthas/VmToolMXBean.java @@ -14,20 +14,22 @@ package arthas; * @author hengyunabc 2021-04-26 */ public interface VmToolMXBean { - /** - * 检测jni-lib是否正常,如果正常,应该输出OK - */ - public String check(); /** * https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#ForceGarbageCollection */ public void forceGc(); + public T[] getInstances(Class klass); + /** * 获取某个class在jvm中当前所有存活实例 + * @param + * @param klass + * @param limit 如果小于 0 ,则不限制 + * @return */ - public T[] getInstances(Class klass); + public T[] getInstances(Class klass, int limit); /** * 统计某个class在jvm中当前所有存活实例的总占用内存,单位:Byte