如何在Linux下通过命令行查看Java应用程序的堆大小(和已使用内存)?
我已经通过jmap试过了。但它提供了信息。关于内部内存区域,如Eden/ PermGen等,这对我来说没什么用。
我想找的是:
最大内存:1GB 最小内存:256mb 堆内存:700mb 已用内存:460mb
这是所有。我知道我可以在JConsole等中看到这一点,但我需要通过命令行来完成。(不能启用JMX等)
如何在Linux下通过命令行查看Java应用程序的堆大小(和已使用内存)?
我已经通过jmap试过了。但它提供了信息。关于内部内存区域,如Eden/ PermGen等,这对我来说没什么用。
我想找的是:
最大内存:1GB 最小内存:256mb 堆内存:700mb 已用内存:460mb
这是所有。我知道我可以在JConsole等中看到这一点,但我需要通过命令行来完成。(不能启用JMX等)
当前回答
到目前为止,还没有这样的工具可以按照您要求的格式打印堆内存 打印的唯一方法是在运行时类的帮助下写一个java程序,
public class TestMemory {
public static void main(String [] args) {
int MB = 1024*1024;
//Getting the runtime reference from system
Runtime runtime = Runtime.getRuntime();
//Print used memory
System.out.println("Used Memory:"
+ (runtime.totalMemory() - runtime.freeMemory()) / MB);
//Print free memory
System.out.println("Free Memory:"
+ runtime.freeMemory() / mb);
//Print total available memory
System.out.println("Total Memory:" + runtime.totalMemory() / MB);
//Print Maximum available memory
System.out.println("Max Memory:" + runtime.maxMemory() / MB);
}
}
参考:https://viralpatel.net/blogs/getting-jvm-heap-size-used-memory-total-memory-using-java-runtime/
其他回答
我觉得jmap已经弃用了。我使用以下命令来监控正在运行的java应用程序的堆。正如在答案中从PS -aux(或使用其他方法)获取PID,并使用该命令
jhsdb jmap --heap --pid <PID>
你可以观察到以下细节;
如果使用jrockit,请尝试jrcmd命令行工具。例如:
$ jrcmd 5127 print_memusage
5127:
Total mapped 1074596KB (reserved=3728KB)
- Java heap 786432KB (reserved=0KB)
- GC tables 26316KB
- Thread stacks 13452KB (#threads=34)
- Compiled code 9856KB (used=9761KB)
- Internal 840KB
- OS 15036KB
- Other 146632KB
- Java class data 75008KB (malloced=74861KB #103221 in 18709 classes)
- Native memory tracking 1024KB (malloced=102KB #8)
对于更多命令,如heap_diagnostics,使用“jrcmd help”列出它们。
https://blogs.oracle.com/jrockit/entry/why_is_my_jvm_process_larger_t
任何方法都应该给出大致相同的数字。使用-X分配堆总是一个好主意。m - x . .每代都是X。然后,您可以保证并执行ps来查看传递了哪些参数并因此使用了哪些参数。
对于实际的内存使用,你可以大致比较VIRT(分配和共享)和RES(实际使用)与jstat值的比较:
对于Java 8,请参阅jstat了解这些值的实际含义。假设您运行一个没有mmap或文件处理的简单类。
$ jstat -gccapacity 32277
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC
215040.0 3433472.0 73728.0 512.0 512.0 67072.0 430080.0 6867968.0 392704.0 392704.0 0.0 1083392.0 39680.0 0.0 1048576.0 4864.0 7225 2
$ jstat -gcutil 32277
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
6.25 0.00 7.96 18.21 98.01 95.29 7228 30.859 2 0.173 31.032
Max:
NGCMX + S0C + S1C + EC + OGCMX + MCMX + CCSMX
3433472 + 512 + 512 + 67072 + 6867968 + 1083392 + 1048576 = 12 GB
(大致接近和低于VIRT内存)
使用最大值(最小值):
215040 + 512 + 512 + 67072 + 430080 + 39680 + 4864 = ~ 1GB
(大致接近RES内存)
“不要引用我的话”,但VIRT mem大致接近或超过最大内存分配,但只要正在使用的内存在物理内存中是空闲的/可用的,JVM就不会抛出内存异常。事实上,在JVM启动时,即使在操作系统上关闭交换,最大内存也不会与物理内存进行检查。本文将更好地解释Java进程实际使用的虚拟内存。
在我的情况下,我需要检查一个docker容器内的标志,它没有大多数基本的实用程序(ps, pstree…)
使用jps,我得到了运行的JVM的PID(在我的情况下1),然后用jcmd 1 VM。我从运行的JVM中获得了这些标志。
这取决于您有哪些可用的命令,但这可能会对某些人有所帮助。:)
该命令以字节为单位显示配置的堆大小。
java -XX:+PrintFlagsFinal -version | grep HeapSize
它也适用于Amazon AMI和EC2。