From 3499a307e2d8258dc170a41e5e5638d067e54214 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Fri, 30 Apr 2021 17:40:08 +0800 Subject: [PATCH] vmtool command support forceGc action. #1781 --- .../src/main/java/arthas/VmTool.java | 7 +++++++ .../src/main/java/arthas/VmToolMXBean.java | 5 +++++ .../src/main/native/include/arthas_VmTool.h | 8 ++++++++ .../src/main/native/src/jni-library.cpp | 19 ++++++++++++------ .../src/test/java/arthas/VmToolTest.java | 4 ++-- .../command/monitor200/VmToolCommand.java | 11 ++++++++-- lib/libArthasJniLibrary-x64.dylib | Bin 52392 -> 53248 bytes spy/src/main/java/arthas/VmTool.java | 7 +++++++ spy/src/main/java/arthas/VmToolMXBean.java | 5 +++++ 9 files changed, 56 insertions(+), 10 deletions(-) diff --git a/arthas-vmtool/src/main/java/arthas/VmTool.java b/arthas-vmtool/src/main/java/arthas/VmTool.java index ae08763d7..d530a06d5 100644 --- a/arthas-vmtool/src/main/java/arthas/VmTool.java +++ b/arthas-vmtool/src/main/java/arthas/VmTool.java @@ -41,6 +41,8 @@ public class VmTool implements VmToolMXBean { */ private static native String check0(); + private static native void forceGc0(); + /** * 获取某个class在jvm中当前所有存活实例 */ @@ -78,6 +80,11 @@ public class VmTool implements VmToolMXBean { return check0(); } + @Override + public void forceGc() { + forceGc0(); + } + @Override public T[] getInstances(Class klass) { return getInstances0(klass); diff --git a/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java b/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java index 51af311ae..92df09be1 100644 --- a/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java +++ b/arthas-vmtool/src/main/java/arthas/VmToolMXBean.java @@ -19,6 +19,11 @@ public interface VmToolMXBean { */ public String check(); + /** + * https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#ForceGarbageCollection + */ + public void forceGc(); + /** * 获取某个class在jvm中当前所有存活实例 */ diff --git a/arthas-vmtool/src/main/native/include/arthas_VmTool.h b/arthas-vmtool/src/main/native/include/arthas_VmTool.h index 3f11b40a6..4f7b087f8 100644 --- a/arthas-vmtool/src/main/native/include/arthas_VmTool.h +++ b/arthas-vmtool/src/main/native/include/arthas_VmTool.h @@ -15,6 +15,14 @@ extern "C" { JNIEXPORT jstring JNICALL Java_arthas_VmTool_check0 (JNIEnv *, jclass); +/* + * Class: arthas_VmTool + * Method: forceGc0 + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_arthas_VmTool_forceGc0 + (JNIEnv *, jclass); + /* * Class: arthas_VmTool * Method: getInstances0 diff --git a/arthas-vmtool/src/main/native/src/jni-library.cpp b/arthas-vmtool/src/main/native/src/jni-library.cpp index 95fab8f62..0351dfead 100644 --- a/arthas-vmtool/src/main/native/src/jni-library.cpp +++ b/arthas-vmtool/src/main/native/src/jni-library.cpp @@ -19,12 +19,6 @@ JNIEXPORT jclass JNICALL getClass(JNIEnv *env) { return cachedClass; } -extern "C" -JNIEXPORT jstring JNICALL -Java_arthas_VmTool_check0(JNIEnv *env, jclass thisClass) { - return env->NewStringUTF("OK"); -} - extern "C" jvmtiEnv *getJvmtiEnv(JNIEnv *env) { @@ -36,6 +30,19 @@ jvmtiEnv *getJvmtiEnv(JNIEnv *env) { return jvmti; } +extern "C" +JNIEXPORT void JNICALL +Java_arthas_VmTool_forceGc0(JNIEnv *env, jclass thisClass) { + jvmtiEnv *jvmti = getJvmtiEnv(env); + jvmti->ForceGarbageCollection(); +} + +extern "C" +JNIEXPORT jstring JNICALL +Java_arthas_VmTool_check0(JNIEnv *env, jclass thisClass) { + return env->NewStringUTF("OK"); +} + extern "C" jobject createJavaInstance(JNIEnv *env, jclass javaClass) { //找到java类的构造方法 diff --git a/arthas-vmtool/src/test/java/arthas/VmToolTest.java b/arthas-vmtool/src/test/java/arthas/VmToolTest.java index 03d3e11a4..16a7bac47 100644 --- a/arthas-vmtool/src/test/java/arthas/VmToolTest.java +++ b/arthas-vmtool/src/test/java/arthas/VmToolTest.java @@ -43,7 +43,7 @@ public class VmToolTest { System.out.println("sum size->" + vmtool.sumInstanceSize(VmTool.class)); beforeInstances = null; - System.gc(); + vmtool.forceGc(); Thread.sleep(100); System.out.println(weakReference1.get() + " " + weakReference2.get()); VmTool[] afterInstances = vmtool.getInstances(VmTool.class); @@ -80,7 +80,7 @@ public class VmToolTest { totalTime.addAndGet(cost); System.out.println(i + " instance size:" + (instances == null ? 0 : instances.length) + ", cost " + cost + "ms avgCost " + totalTime.doubleValue() / i + "ms"); instances = null; - System.gc(); + vmtool.forceGc(); } } 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 bd17d6e16..05ab8cd12 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 @@ -46,7 +46,8 @@ import arthas.VmTool; @Summary("jvm tool") @Description(Constants.EXAMPLE + " vmtool --action getInstances --className demo.MathGame\n" - + " vmtool --action getInstances --className demo.MathGame --express 'instances.size()'\n" + + " vmtool --action getInstances --className demo.MathGame --express 'instances.length'\n" + + " vmtool --action forceGc\n" + Constants.WIKI + Constants.WIKI_HOME + "vmtool") //@formatter:on public class VmToolCommand extends AnnotatedCommand { @@ -123,7 +124,7 @@ public class VmToolCommand extends AnnotatedCommand { } public enum VmToolAction { - getInstances, load + getInstances, forceGc, load } @Override @@ -178,8 +179,14 @@ public class VmToolCommand extends AnnotatedCommand { } process.write(new ObjectView(value, this.expand).draw()); + process.write("\n"); process.end(); } + } else if (VmToolAction.forceGc.equals(action)) { + vmToolInstance().forceGc(); + process.write("\n"); + process.end(); + return; } process.end(); diff --git a/lib/libArthasJniLibrary-x64.dylib b/lib/libArthasJniLibrary-x64.dylib index 8ab0de5863792556d53b295b19beafe6d9d12d73..5547993f54f3f17dad8737f111553030136e765f 100644 GIT binary patch literal 53248 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 delta 3310 zcmZ`*dr(x@8UOCRyDRcqKv60xG%YC>WiKEgZ_r%5;A^SUX>D{_mqoy3AMrdCN}>^kivmp;ZcnKty{(C^#_Ne#KP z=YHpV{mwbx9Oh zeFfhVkPp~Oh9zI+Ow4i8%w;p_q?;?qJnmEc6BGiJ=VX{H9nYRmCQZ8144230w7X2l zdR#|MR+qcO+DC{^AUAaD8_%!+u}c8?=s%CNgTrm$JPXIED*$VePD}vAQJ#czGYT`3b+5 zbej^^6d*4K20jvlyCu;-{Ti?g?-%|gDN#}k+La%vQ z9cYnI7e#Rdq~_G&)kVh`_I4@>6$jYnRI;w5AVEw9FebH!NQ}?s+mJzrb|lgyM&>gx z;UkfP`L7_*Z>eT*Ecf8$;m3+rFzg%2B(gcc6p^(h8`=Cs(p9?CbmFf*Jf`T!?fX6G z*Ak~kk<9;ISU}KOF`!?k;Ky*9m_+WBW_f?G9KbJ(4GxTf@#K1R4|vAJV9iw&*CoW~(lR-yOfWV%(7!*cd!_?BFtX)`GX!J*=;-#^lRj_j@_HqsU zeR85K&--4&lDj#sc+8-7aW_MBEjd%ACs8f+Q>9-Bt2+!!H~%H?@QfzFy!Fr}gDDPb zU#QrJ#s!K50b!_0*fC-ZZqjfA9&~L9i2>ofXxlv`29hT*B8ljRwu4c|FAU9%<4Mur z3@$v6bY46$=0kt-f~kOXmA_AJ7H%3oS(J$BT88=mE}O-WzZCOq(K5LV^7U#NL`v5% z{~!ewh2D$0B?FL*mbf_8E(Rd!^Xd5B{FkT0g88TE@GOlzi(g{7nhR$`Q>3TV#sJ% z@|MOvrC_h1*knuf7G{h*QoSm{s)$F)Q`OtOpZ;BjkBmID7 zAJuBap+ozY(mB0tl3|&A$Kw>D3@{-S;unUAV8g@{kS5A^{;=6_ceOWSqGkX-1f&m7 zzax~ED-<-U+NJS|oLBi!rNXC`DKxBp*uyGcuTk|Y-lS3$eRz){BOiCtv-;_%jxiE_ z)J=R-spOUDj-;|}R)<45Itjd$OFoRIlCEn;a_-F&ByD;vv0nN$VP~vmAqC6Tkx_54 zSo+*n+fj?H*{p6+mXYEv49@*uIxt#BmTo3vP$qO%MI;-GbR%uFNbj!;$mX9`OE=+urGHlO5${ zFHqP+!096Rg19`hARB6>tc@z#aOT5uXSI{V8C`?Jv8%`0W>=8x7>jo?Oh{hVDN&1I zXrk1q2!5(BE^l<(U6_l#Bx&Y5x?dUa4^Zy-H`reqNO=02?5hTveshM2~`-etzolQ5v)=L+MnGbjjvMlEh-+0=$JoUZ6r|;ml4xKdACrzc;JAS8MzqsRHc+_>IP^7rSwk`> f9pw4R3wRMVf8i23bnO|ezN>igJWhT*V`JcdMf8$1 diff --git a/spy/src/main/java/arthas/VmTool.java b/spy/src/main/java/arthas/VmTool.java index ae08763d7..d530a06d5 100644 --- a/spy/src/main/java/arthas/VmTool.java +++ b/spy/src/main/java/arthas/VmTool.java @@ -41,6 +41,8 @@ public class VmTool implements VmToolMXBean { */ private static native String check0(); + private static native void forceGc0(); + /** * 获取某个class在jvm中当前所有存活实例 */ @@ -78,6 +80,11 @@ public class VmTool implements VmToolMXBean { return check0(); } + @Override + public void forceGc() { + forceGc0(); + } + @Override public T[] getInstances(Class klass) { return getInstances0(klass); diff --git a/spy/src/main/java/arthas/VmToolMXBean.java b/spy/src/main/java/arthas/VmToolMXBean.java index 51af311ae..92df09be1 100644 --- a/spy/src/main/java/arthas/VmToolMXBean.java +++ b/spy/src/main/java/arthas/VmToolMXBean.java @@ -19,6 +19,11 @@ public interface VmToolMXBean { */ public String check(); + /** + * https://docs.oracle.com/javase/8/docs/platform/jvmti/jvmti.html#ForceGarbageCollection + */ + public void forceGc(); + /** * 获取某个class在jvm中当前所有存活实例 */