Skip to content

Commit 502a048

Browse files
authored
Add mallocTrim command to vmTool (#3030)
1 parent 0596202 commit 502a048

File tree

7 files changed

+131
-2
lines changed

7 files changed

+131
-2
lines changed

arthas-vmtool/src/main/java/arthas/VmTool.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,16 @@ public Class<?>[] getAllLoadedClasses() {
116116
return getAllLoadedClasses0(Class.class);
117117
}
118118

119+
@Override
120+
public int mallocTrim() {
121+
return mallocTrim0();
122+
}
123+
124+
private static synchronized native int mallocTrim0();
125+
126+
@Override
127+
public boolean mallocStats() {
128+
return mallocStats0();
129+
}
130+
private static synchronized native boolean mallocStats0();
119131
}

arthas-vmtool/src/main/java/arthas/VmToolMXBean.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,14 @@ public interface VmToolMXBean {
5757
* 获取所有已加载的类
5858
*/
5959
public Class<?>[] getAllLoadedClasses();
60+
61+
/**
62+
* glibc 释放空闲内存
63+
*/
64+
public int mallocTrim();
65+
66+
/**
67+
* glibc 输出内存状态到应用的 stderr
68+
*/
69+
public boolean mallocStats();
6070
}

arthas-vmtool/src/main/native/src/jni-library.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include <jvmti.h>
55
#include "arthas_VmTool.h" // under target/native/javah/
66

7+
#ifdef __GLIBC__
8+
#include <malloc.h>
9+
#endif
710

811
static jvmtiEnv *jvmti;
912
static jlong tagCounter = 0;
@@ -204,4 +207,24 @@ JNIEXPORT jobjectArray JNICALL Java_arthas_VmTool_getAllLoadedClasses0
204207
}
205208
jvmti->Deallocate(reinterpret_cast<unsigned char *>(classes));
206209
return array;
207-
}
210+
}
211+
212+
extern "C"
213+
JNIEXPORT jint JNICALL Java_arthas_VmTool_mallocTrim0
214+
(JNIEnv *env, jclass thisClass) {
215+
#ifdef __GLIBC__
216+
return ::malloc_trim(0);
217+
#endif
218+
return -1;
219+
}
220+
221+
extern "C"
222+
JNIEXPORT jboolean JNICALL Java_arthas_VmTool_mallocStats0
223+
(JNIEnv *env, jclass thisClass) {
224+
#ifdef __GLIBC__
225+
::malloc_stats();
226+
return JNI_TRUE;
227+
#else
228+
return JNI_FALSE;
229+
#endif
230+
}

arthas-vmtool/src/test/java/arthas/VmToolTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,16 @@ public void test_interrupt_thread() throws InterruptedException {
210210
TimeUnit.SECONDS.sleep(5);
211211
Assert.assertEquals(("interrupted " + interruptMe.getId() + " thread success."), re[0].getMessage());
212212
}
213+
214+
@Test
215+
public void testMallocTrim() {
216+
VmTool vmtool = initVmTool();
217+
vmtool.mallocTrim();
218+
}
219+
220+
@Test
221+
public void testMallocStats() {
222+
VmTool vmtool = initVmTool();
223+
vmtool.mallocStats();
224+
}
213225
}

core/src/main/java/com/taobao/arthas/core/command/monitor200/VmToolCommand.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
+ " vmtool --action getInstances --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --className org.springframework.context.ApplicationContext\n"
5757
+ " vmtool --action forceGc\n"
5858
+ " vmtool --action interruptThread -t 1\n"
59+
+ " vmtool --action mallocTrim\n"
60+
+ " vmtool --action mallocStats\n"
5961
+ Constants.WIKI + Constants.WIKI_HOME + "vmtool")
6062
//@formatter:on
6163
public class VmToolCommand extends AnnotatedCommand {
@@ -157,7 +159,7 @@ public void setThreadId(int threadId) {
157159
}
158160

159161
public enum VmToolAction {
160-
getInstances, forceGc, interruptThread
162+
getInstances, forceGc, interruptThread, mallocTrim, mallocStats
161163
}
162164

163165
@Override
@@ -239,6 +241,18 @@ public void process(final CommandProcess process) {
239241
process.end();
240242

241243
return;
244+
} else if (VmToolAction.mallocTrim.equals(action)) {
245+
int result = vmToolInstance().mallocTrim();
246+
process.write("\n");
247+
process.end(result == 1 ? 0 : -1, "mallocTrim result: " +
248+
(result == 1 ? "true" : (result == 0 ? "false" : "not supported")));
249+
return;
250+
} else if (VmToolAction.mallocStats.equals(action)) {
251+
boolean result = vmToolInstance().mallocStats();
252+
process.write("\n");
253+
process.end(result ? 0 : -1, "mallocStats result: " +
254+
(result ? "true" : "not supported"));
255+
return;
242256
}
243257

244258
process.end();

site/docs/doc/vmtool.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,32 @@ thread id 通过`-t`参数指定,可以使用 `thread`命令获取。
9797
```bash
9898
vmtool --action interruptThread -t 1
9999
```
100+
101+
## glibc 释放空闲内存
102+
103+
Linux man page: [malloc_trim](https://man7.org/linux/man-pages/man3/malloc_trim.3.html)
104+
105+
```bash
106+
vmtool --action mallocTrim
107+
```
108+
109+
## glibc 内存状态
110+
111+
内存状态将会输出到应用的 stderr。Linux man page: [malloc_stats](https://man7.org/linux/man-pages/man3/malloc_stats.3.html)
112+
113+
```bash
114+
vmtool --action mallocStats
115+
```
116+
117+
输出到 stderr 的内容如下:
118+
119+
```
120+
Arena 0:
121+
system bytes = 135168
122+
in use bytes = 74352
123+
Total (incl. mmap):
124+
system bytes = 135168
125+
in use bytes = 74352
126+
max mmap regions = 0
127+
max mmap bytes = 0
128+
```

site/docs/en/doc/vmtool.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,32 @@ The thread id is specified by the `-t` parameter. It can be obtained using the `
9797
```bash
9898
vmtool --action interruptThread -t 1
9999
```
100+
101+
## glibc Release Free Memory
102+
103+
Linux man page: [malloc_trim](https://man7.org/linux/man-pages/man3/malloc_trim.3.html)
104+
105+
```bash
106+
vmtool --action mallocTrim
107+
```
108+
109+
## glibc Memory Status
110+
111+
The memory status will be output to the application's stderr. Linux man page: [malloc_stats](https://man7.org/linux/man-pages/man3/malloc_stats.3.html)
112+
113+
```bash
114+
vmtool --action mallocStats
115+
```
116+
117+
The output to stderr is as follows:
118+
119+
```
120+
Arena 0:
121+
system bytes = 135168
122+
in use bytes = 74352
123+
Total (incl. mmap):
124+
system bytes = 135168
125+
in use bytes = 74352
126+
max mmap regions = 0
127+
max mmap bytes = 0
128+
```

0 commit comments

Comments
 (0)