如何通过命令行检查 Linux 上 Java 应用程序的堆大小(和已用内存)?
我已经通过jmap尝试过。但它提供信息。关于 Eden/PermGen 等内部存储区域,这对我没有用。
我正在寻找类似的东西:
- 最大内存:1GB
- 最小内存:256 MB
- 堆内存:700 MB
- 已用内存:460 MB
就这样。我知道我可以在 JConsole 等中看到这一点,但我需要通过命令行来完成。(无法启用 JMX 等)
如何通过命令行检查 Linux 上 Java 应用程序的堆大小(和已用内存)?
我已经通过jmap尝试过。但它提供信息。关于 Eden/PermGen 等内部存储区域,这对我没有用。
我正在寻找类似的东西:
就这样。我知道我可以在 JConsole 等中看到这一点,但我需要通过命令行来完成。(无法启用 JMX 等)
每个 Java 进程都有一个pid
,您首先需要使用jps
命令找到它。
获得 pid 后,您可以使用它jstat -gc [insert-pid-here]
来查找垃圾收集堆行为的统计信息。
jstat -gccapacity [insert-pid-here]
将显示有关内存池生成和空间功能的信息。
jstat -gcutil [insert-pid-here]
将显示每一代的利用率占其容量的百分比。有助于一目了然地了解使用情况。
请参阅Oracle 网站上的jstat 文档。
此命令显示配置的堆大小(以字节为单位)。
java -XX:+PrintFlagsFinal -version | grep HeapSize
它也适用于 EC2 上的 Amazon AMI。
jvmtop是一个命令行工具,它提供多个指标的实时视图,包括堆。
JvmTop 0.3 alpha (expect bugs) amd64 8 cpus, Linux 2.6.32-27, load avg 0.12
http://code.google.com/p/jvmtop
PID MAIN-CLASS HPCUR HPMAX NHCUR NHMAX CPU GC VM USERNAME #T DL
3370 rapperSimpleApp 165m 455m 109m 176m 0.12% 0.00% S6U37 web 21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager 11m 28m 23m 130m 0.00% 0.00% S6U37 web 31
19187 m.jvmtop.JvmTop 20m 3544m 13m 130m 0.93% 0.47% S6U37 web 20
16733 artup.Bootstrap 159m 455m 166m 304m 0.12% 0.00% S6U37 web 46
试试这个它在 Ubuntu 和 RedHat 中工作:
java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
对于 Windows:
java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"
对于 Mac
java -XX:+PrintFlagsFinal -version | grep -iE 'heapsize|permsize|threadstacksize'
所有这些命令的输出类似于以下输出:
uintx InitialHeapSize := 20655360 {product}
uintx MaxHeapSize := 331350016 {product}
uintx PermSize = 21757952 {pd product}
uintx MaxPermSize = 85983232 {pd product}
intx ThreadStackSize = 1024 {pd product}
java version "1.7.0_05"
Java(TM) SE Runtime Environment (build 1.7.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)
要找到以 MB 为单位的大小,请将该值除以 (1024*1024)。
如果不使用大多数工具使用的 JMX,您所能做的就是使用
jps -lvm
并推断设置将来自命令行选项。
默认情况下,如果没有 JMX,您将无法获取动态信息,但您可以编写自己的服务来执行此操作。
顺便说一句:我更喜欢使用 VisualVM 而不是 JConsole。
有一个具有视觉方面的命令行工具 - jvm-mon。它是一个用于命令行的 JVM 监控工具,它显示:
工具打开时,指标和图表会更新。
从Java8 及更高版本,您可以使用以下命令:
jcmd JAVA_PROCESS_ID
GC.heap_info
您可以参考输出中的总内存、总内存和已用内存。
Sample Command And Output: jcmd 9758 GC.heap_info
PSYoungGen total 1579520K, used 487543K [0x0000000751d80000, 0x00000007c0000000, 0x00000007c0000000)
eden space 1354240K, 36% used [0x0000000751d80000,0x000000076f99dc40,0x00000007a4800000)
from space 225280K, 0% used [0x00000007b2400000,0x00000007b2400000,0x00000007c0000000)
to space 225280K, 0% used [0x00000007a4800000,0x00000007a4800000,0x00000007b2400000)
ParOldGen total 3610112K, used 0K [0x0000000675800000, 0x0000000751d80000, 0x0000000751d80000)
object space 3610112K, 0% used [0x0000000675800000,0x0000000675800000,0x0000000751d80000)
Metaspace used 16292K, capacity 16582K, committed 16896K, reserved 1064960K
class space used 1823K, capacity 1936K, committed 2048K, reserved 1048576K
有关 jcmd 命令的更多详细信息,请访问此处的链接
聚会迟到了,但一个非常简单的解决方案是使用 jpsstat.sh 脚本。它提供了一个简单的实时当前内存、最大内存和cpu 使用详细信息。
这是脚本的示例输出 -
===== ====== ======= ======= =====
PID Name CurHeap MaxHeap %_CPU
===== ====== ======= ======= =====
2777 Test3 1.26 1.26 5.8
2582 Test1 2.52 2.52 8.3
2562 Test2 2.52 2.52 6.4
在我的情况下,我需要检查一个 docker 容器中的标志,该容器没有大多数基本实用程序(ps,pstree ...)
使用jps
我得到了正在运行的 JVM 的 PID(在我的情况下为 1),然后jcmd 1 VM.flags
我从正在运行的 JVM 中得到了标志。
这取决于您可以使用哪些命令,但这可能会对某人有所帮助。:)
任何方法都应该给你大致相同的数字。-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
最大:
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 进程真正使用的虚拟内存的更好解释。
在 Java 堆大小方面,在 Linux 中,您可以使用
ps aux | grep java
或者
ps -ef | grep java
并查找 -Xms、-Xmx 以找出指定的初始和最大堆大小。
但是,如果您感兴趣的 Java 进程没有 -Xms 或 -Xmx,则意味着您的 Java 进程正在使用默认堆大小。您可以使用以下命令找出默认大小。
java -XX:+PrintFlagsFinal -version | grep HeapSize
或特定的 jvm,例如,
/path/to/jdk1.8.0_102/bin/java -XX:+PrintFlagsFinal -version | grep HeapSize
并查找以字节为单位的 InitialHeapSize 和 MaxHeapSize。
首先从以下一项中获取进程 ID,即列出的进程中的第一个数字:(或仅使用ps aux | grep java
,如果您愿意的话)
jps -lvm
然后在此处使用进程 ID:
jmap -heap $MY_PID 2>/dev/null | sed -ne '/Heap Configuration/,$p';
jmap -permstat $MY_PID
到目前为止,还没有这样的工具可以按照您要求的格式打印堆内存 唯一也是唯一的打印方法是在 Runtime Class 的帮助下编写一个 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/
使用top
命令是检查程序内存使用情况的最简单方法。RES
列显示进程占用的实际物理内存。
就我而言,我在 java 中读取了一个 10g 的文件,并且每次遇到 outOfMemory 异常。当RES
列中的值达到-Xmx
选项中设置的值时,就会发生这种情况。然后通过使用选项增加内存-Xmx
一切都很好。
如果使用 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
jstat -gccapacity javapid (ex. stat -gccapacity 28745)
jstat -gccapacity javapid gaps frames (ex. stat -gccapacity 28745 550 10 )
上述命令的示例 O/P
NGCMN NGCMX NGC S0C
87040.0 1397760.0 1327616.0 107520.0
NGCMN Minimum new generation capacity (KB).
NGCMX Maximum new generation capacity (KB).
NGC Current new generation capacity (KB).
在http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstat.html获取更多详细信息