IMLC.ME

JVM 基础参数一览

Xms 和 Xmx

Xms 和 Xmx 可谓是 Java 性能调优中最基础、最常用也最重要的参数。

Xms 指定堆的最小大小,也即初始大小。 Xmx 指定堆的最大大小。

参数格式如下:

-Xms<size>[g|G|m|M|k|K]
-Xmx<size>[g|G|m|M|k|K]

其中单位 "g/G" 表示 GB,"m/M" 表示 MB,"k/K" 表示 KB。 例如 java -Xms1024M 表示 JVM 的最小堆大小为 1024M。

如果最小堆大小过小,程序启动后会频繁遇到内存不足,继而需要频繁 GC,影响影响。

如果最大堆大小过大,程序会久久不触发 GC。这会让单次 GC 需要回收的内存过多,延长了 GC 时间。

MaxMetaspaceSize

MaxMetaspaceSize 指定元数据空间大小。其格式为:

-XX:MaxMetaspaceSize=<metaspace size>[g|G|m|M|k|K]

元数据空间 Metaspace 处于本地堆空间中,用于储存类的元数据。如果 Metaspace 空间不足,应用程序会抛出 OutOfMemoryError。 触发 Metaspace OOM 最常见的场景是,应用程序会有太多动态生成的类,撑爆了 Metaspace。

NewSize 和 MaxNewSize

-XX:NewSize=<young size>[unit]
-XX:MaxNewSize=<young size>[unit]

NewSize 和 MaxNewSize 用于设置新生代的初始和最大大小。一般建议设为堆大小的 1/4 或 1/3,并且两者设为同样大小。

GC 日志

-XX:+PrintGCDetails 打印 GC 细节
-XX:+PrintGCDateStamps 打印 GC 时间戳
-XX:+UseGCLogFileRotation 启动 GC 日志文件滚动。即当 GC 日志文件到达 "GCLogFileSize" 指定的大小时,会把归档当前文件并重命名。然后新日志写入新文件。避免单一文件过大。
-XX:NumberOfGCLogFiles=< number of log files > 可以滚动多少个日志文件。超过限制,最旧的文件会被抛弃。
-XX:GCLogFileSize=< file size >[ unit ] 单个 GC 日志文件大小
-Xloggc:/path/to/gc.log GC 文件路径

OOM 日志

下方参数用于在 Java 程序发生 OOM 后,自动做 heap dump。 如果在生产环境中如果发生 OOM,而测试环境又无法重现时,相信我,你是心里肯定是崩溃的。 所以在生产环境中运行 Java 程序,下方的参数是必不可少的。它最少最少可以为你提供 debug 的线索和方向。

-XX:+HeapDumpOnOutOfMemoryError 启动 OOM 后自动 heap dump
-XX:HeapDumpPath=./java_pid<pid>.hprof heap dump 文件储存路径
-XX:OnOutOfMemoryError="< cmd args >;< cmd args >" 发生 OOM 后执行命令

说到生产环境,一般来说开发不能直接登录生产环境。 更严格一点,生产环境不允许任何人登录。所以 hprof 虽然 dump 了出来,但是未必能拿得到。 所以开启这项功能的同时,也要配套相应的文件转存服务。

参考资料

https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html

https://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace