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
指定元数据空间大小。其格式为:
-XX:MaxMetaspaceSize=<metaspace size>[g|G|m|M|k|K]
元数据空间 Metaspace 处于本地堆空间中,用于储存类的元数据。如果 Metaspace 空间不足,应用程序会抛出 OutOfMemoryError。
触发 Metaspace OOM 最常见的场景是,应用程序会有太多动态生成的类,撑爆了 Metaspace。
-XX:NewSize=<young size>[unit]
-XX:MaxNewSize=<young size>[unit]
NewSize 和 MaxNewSize 用于设置新生代的初始和最大大小。一般建议设为堆大小的 1/4 或 1/3,并且两者设为同样大小。
-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 文件路径
下方参数用于在 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