1.概述
在本快速教程中,我们将探索可用于配置Java虚拟机的最常见选项。
2.显式堆内存–Xms和Xmx选项
最常见的性能相关实践之一是根据应用程序要求初始化堆内存。
这就是为什么我们应该指定最小和最大堆大小。以下参数可用于实现:
-Xms<堆大小>[单位]
-Xmx<堆大小>[单位]
复制
这里,unit表示要初始化内存(由堆大小表示)的单元。单位可以标记为“g”表示GB,“m”表示MB,“k”表示KB。
例如,如果我们想为JVM分配最小2 GB和最大5 GB,我们需要写:
自由星
-Xms2G-Xmx5G
复制
从Java 8开始,未定义Metaspace的大小。一旦达到全局限制,JVM会自动增加它。然而,为了克服任何不必要的不稳定性,我们可以使用以下方法设置元空间大小:
-xx: MaxMetaspaceSize=<元空间大小>[单位]
复制
这里,元空间大小表示要分配给元空间的内存量。
根据Oracle指南,在总可用内存之后,第二大影响因素是为年轻一代保留的堆的比例。默认情况下,YG的最小大小为1310 MB,最大大小不受限制。
我们可以明确指定它们:
-xx: NewSize=<年轻尺寸>[单位]
-xx: MaxNewSize=<年轻尺寸>[单位]
复制
3.垃圾收集
为了提高应用程序的稳定性,选择正确的垃圾收集算法至关重要。
自由星
JVM有四种类型的GC实现:
串行垃圾收集器
并行垃圾收集器
CMS垃圾收集器
G1垃圾收集器
可以使用以下参数声明这些实现:
-xx: +使用序列GC
-xx: +使用并行GC
-xx: +USeParNewGC
-xx: +使用G1GC
复制
有关垃圾收集实现的更多详细信息,请参见此处。
4. GC记录
为了严格监控应用程序的运行状况,我们应该始终检查JVM的垃圾收集性能。最简单的方法是以人类可读的格式记录GC活动。
使用以下参数,我们可以记录GC活动:
-xx: +使用GCLogFileRotation
-xx: NumberOfGCLogFiles=<日志文件数>
-xx: GCLogFileSize=<文件大小>[单位]
-Xloggc:/path/to/gc.log
复制
UseGCLogFileRotation指定日志文件滚动策略,非常类似于log4j、s4lj等。NumberOfGCLogFiles表示单个应用程序生命周期可以写入的日志文件的最大数量。GCLogFileSize指定文件的最大大小。最后,loggc表示其位置。
这里需要注意的是,还有两个JVM参数(-XX:+PrintGCTimeStamps和-XX:+PrintGCDateStamps)可用于打印GC日志中的日期时间戳。
例如,如果我们希望分配最多100个GC日志文件,每个文件的最大大小为50 MB,并希望将它们存储在“/home/user/log/”位置,我们可以使用以下语法:
-xx: +使用GCLogFileRotation
-xx: GCLogFiles数=10
-xx: GCLogFileSize=50M
-Xloggc:/home/user/log/gc.log
复制
然而,问题是,一个额外的守护进程线程总是用于后台监控系统时间。这种行为可能会造成一些性能瓶颈;这就是为什么在生产中最好不要使用这个参数。
5.处理内存不足
对于大型应用程序来说,内存不足错误是很常见的,这反过来会导致应用程序崩溃。这是一个非常关键的场景,很难复制来解决问题。
这就是JVM附带一些参数的原因,这些参数将堆内存转储到一个物理文件中,稍后可以用来查找泄漏:
-xx: +堆转储OnOutOfMemoryError
-xx: 堆转储路径=./java_pid<pid>.hprof
-xx: OnOutOfMemoryError=“<cmd args>;<cmd args>”
-xx: +使用GCOverheadLimit
复制
这里需要注意几点:
HeapDumpOnOutOfMemoryError指示JVM在OutOf记忆错误的情况下将堆转储到物理文件中
HeapDumpPath表示要写入文件的路径;可以给出任何文件名;但是,如果JVM在名称中找到<pid>标记,则导致内存不足错误的当前进程的进程id将以.hprof格式附加到文件名中
OnOutOfMemoryError用于在内存不足错误时发出紧急命令;应该在cmd参数的空间中使用适当的命令。例如,如果我们希望在内存不足时立即重新启动服务器,我们可以设置参数:
-xx: OnOutOfMemoryError=“shutdown-r”
复制
UseGCOverheadLimit是一种策略,用于限制抛出OutOfMemory错误之前VM在GC中花费的时间比例
6. 32/64位
在安装了32位和64位软件包的操作系统环境中,JVM会自动选择32位环境软件包。
如果我们想手动将环境设置为64位,可以使用以下参数:
-d<操作系统位>
复制
操作系统位可以是32或64。有关这一点的更多信息,请参阅此处。
7.其他
-服务器:启用“服务器热点VM”;在64位JVM中默认使用此参数
-xx: +UseStringDeduplication:Java 8u20引入了这个JVM参数,通过创建太多相同String的实例来减少不必要的内存使用;这通过将重复的String值减少到单个全局char[]数组来优化堆内存
-xx: +UseLWPSynchronization:设置基于LWP(轻量级进程)的同步策略,而不是基于线程的同步
-xx: LargePageSizeInBytes:设置用于Java堆的大页面大小;它以GB/MB/KB为单位接受参数;使用更大的页面大小,我们可以更好地利用虚拟内存硬件资源;然而,这可能会导致PermGen的空间大小变大,这反过来会迫使Java堆空间的大小减小
-xx: MaxHeapFreeRatio:设置GC后堆空闲的最大百分比,以避免收缩。
-xx: MinHeapFreeRatio:设置GC后堆空闲的最小百分比,以避免扩展;要监视堆使用情况,可以使用JDK附带的VisualVM。
-xx: SurvivorRatio:伊甸园/幸存者空间大小的比率–例如,-XX:survivor Ratio=6将每个幸存者空间和伊甸园空间之间的比率设置为1:6,
-xx: +UseLargePages:如果系统支持,则使用大页面内存;请注意,如果使用此JVM参数,OpenJDK 7会崩溃
-xx: +UseStringCache:启用字符串池中可用的常用分配字符串的缓存
-xx: +UseCompressedStrings:对可以用纯ASCII格式表示的String对象使用byte[]类型
-xx: +OptimizeStringConcat:它尽可能优化字符串连接操作
8.结论
在这篇快速文章中,我们了解了一些重要的JVM参数,这些参数可用于调整和改进一般应用程序性能。
其中一些还可以用于调试目的。
如果您想更详细地研究参考参数,可以从这里开始。