san*_*ity 10 java performance garbage-collection jvm jvm-arguments
我在一台具有16Gb RAM,8核处理器和Java 1.6的机器上运行内存密集型应用程序,所有这些都运行在CentOS 5.2版(最终版)上.精确的JVM详细信息是:
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) 64-Bit Server VM (build 11.0-b15, mixed mode)
Run Code Online (Sandbox Code Playgroud)
我正在使用以下命令行选项启动应用程序:
java -XX:+UseConcMarkSweepGC -verbose:gc -server -Xmx10g -Xms10g ...
Run Code Online (Sandbox Code Playgroud)
我的应用程序公开了一个JSON-RPC API,我的目标是在25ms内响应请求.不幸的是,我看到延迟超过1秒,似乎是垃圾收集造成的.以下是一些较长的例子:
[GC 4592788K->4462162K(10468736K), 1.3606660 secs]
[GC 5881547K->5768559K(10468736K), 1.2559860 secs]
[GC 6045823K->5914115K(10468736K), 1.3250050 secs]
Run Code Online (Sandbox Code Playgroud)
这些垃圾收集事件中的每一个都伴随着延迟的API响应,其持续时间与显示的垃圾收集的长度非常相似(在几毫秒内).
以下是一些典型示例(这些示例均在几秒钟内生成):
[GC 3373764K->3336654K(10468736K), 0.6677560 secs]
[GC 3472974K->3427592K(10468736K), 0.5059650 secs]
[GC 3563912K->3517273K(10468736K), 0.6844440 secs]
[GC 3622292K->3589011K(10468736K), 0.4528480 secs]
Run Code Online (Sandbox Code Playgroud)
问题是我认为UseConcMarkSweepGC可以避免这种情况,或者至少使它非常罕见.相反,超过100毫秒的延迟几乎每分钟发生一次或更多(尽管超过1秒的延迟相当罕见,可能每10或15分钟一次).
另一件事是我认为只有一个FULL GC会导致线程被暂停,但这些似乎不是完整的GC.
可能需要注意的是,大多数内存都是由使用软引用的LRU内存缓存占用的.
任何帮助或建议将不胜感激.
Edd*_*die 11
首先,查看Java SE 6 HotSpot [tm]虚拟机垃圾收集调整文档,如果您还没有这样做的话.该文档说:
并发收集器在应用程序线程仍在运行时执行大部分跟踪和扫描工作,因此应用程序线程只能看到短暂的暂停.但是,如果并发收集器无法在终端生成填满之前完成回收无法访问的对象,或者如果无法满足终生代中可用空闲块的分配,则暂停应用程序并完成收集所有应用程序线程都停止了 无法同时完成收集称为并发模式失败,表示需要调整并发收集器参数.
稍后......
并发收集器在并发收集周期期间暂停应用程序两次.
我注意到那些GC似乎没有释放太多的内存.也许你的许多物品都是长寿的?您可能希望调整生成大小和其他GC参数.根据许多标准,10 Gig是一个巨大的堆,我天真地期望GC需要更长时间才能拥有如此庞大的堆.仍然,1秒是一个非常长的暂停时间,并指示出现问题(您的程序正在生成大量不需要的对象或生成难以回收的对象,或其他东西)或者您只需要调整GC.
通常,我会告诉别人如果他们必须调整GC,那么他们还有其他需要先解决的问题.但是,对于这种规模的应用,我认为你应该进入"需要比普通程序员更多地理解GC"的领域.
正如其他人所说,您需要分析您的应用程序以查看瓶颈所在.你的PermGen对于分配给它的空间来说太大了吗?你在创造不必要的物品吗?jconsole至少可以显示有关VM的最少信息.这是一个起点.然而,正如其他人指出的那样,您很可能需要比此更高级的工具.
祝好运.
eri*_*son 11
既然你提到了缓存的愿望,我猜你的大堆大部分都被缓存占用了.您可能希望限制缓存的大小,以确保它永远不会尝试增长到足以填充终生代.不要SoftReference
单独依靠限制尺寸.由于旧一代填充了软引用,旧的引用将被清除并变成垃圾.将创建新的引用(可能是相同的信息),但由于可用空间短缺,因此可以快速清除.最终,终身空间充满垃圾,需要清理.
考虑调整-XX:NewRatio
设置.默认值为1:2,表示堆的三分之一分配给新一代.对于大堆,这几乎总是太多.你可能想尝试像9这样的东西,这将为你的老一代保留9 Gb的10 Gb堆.
事实证明,堆的一部分被交换到了磁盘,因此垃圾收集必须将一堆数据从磁盘中拉回内存.
我通过将Linux的"swappiness"参数设置为0来解决此问题(因此它不会将数据交换到磁盘).
归档时间: |
|
查看次数: |
12868 次 |
最近记录: |