我使用的是Java 5,我们的自定义服务器应用程序需要GC调优,因为有时我们会在高峰时段暂停15-20秒。我们在服务器类机器上运行Java 5,该机器具有类似-server -d64
的JVM参数
有没有一种方法可以告诉JVM当前使用的是哪种GC算法?
http://docs.oracle.com/javase/1.5.0/docs/guide/vm/gc-ergonomics.html
在运行服务器VM的服务器类机器上,垃圾收集器(GC)已从以前的串行收集器(-XX:+UseSerialGC
)更改为并行收集器(-XX:+UseParallelGC
)。您可以通过对java命令使用-XX:+UseSerialGC
命令行选项来覆盖此默认值。
1) 我想知道这真的发生了吗?
我的下一个问题是我在命令行参数中添加了以下内容
-verbose:gc-XX:+PrintGCTimeStamps-XX:+PrintGCDetails-XX:+PraintGCApplicationStoppedTime-XX:+PprintGCApplicationConcurrentTime-Xloggc:logs/gc.log
2) 除了记录GC日志之外,它们会对正在运行的JVM产生任何性能或行为影响吗?
您可以使用-XX:+PrintFlagsFinal打印JVM参数及其设置。
java-XX:+PrintFlagsFinal-server-版本
您可以使用jmap -heap <jvm_pid>
打印java堆摘要。例如,如果我运行jmap -heap 2592
:,Intellij的堆摘要如下所示
正在附加进程ID 2592,请稍候
附加的调试器成功
检测到服务器编译器
JVM版本为25.101-b13在新一代中使用并行线程
使用线程本地对象分配
并发标记扫描GC
已截断
您可以从输出中发现,使用2592进程id运行的JVM实例使用CMSGC算法。
此外,如果算法是由这些-XX:+Use*GC
标志确定的,则可以使用jcmd <pid> VM.flags
找到它。例如:
$ jcmd 2715 VM.flags
2715:
-XX:CICompilerCount=4 -XX:InitialHeapSize=268435456
-XX:MaxHeapSize=734003200 -XX:MaxNewSize=244318208
-XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:OldSize=179306496
-XX:+UseCompressedClassPointers -XX:+UseCompressedOops
-XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
正如您所看到的,VM正在使用并行GC。
您可以使用GarbageCollectorMXBeans获取当前正在使用的gc。
几乎所有日志记录都会对性能产生影响。
将Visual VM附加到进程并检查mbeans。如果你以前从未使用过它(它是Oracle JDK下载的一部分),你可能需要安装MBean插件(这很容易)
http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/
http://visualvm.java.net/mbeans_tab.html
如果GC正在成为一个问题,我建议您研究一下Java RTS(实时系统)
Java RTS允许您精确控制GC何时工作。这意味着你可以完全控制最坏的情况,因此,可以模拟你的系统在充满压力的情况下的表现。