【发布时间】:2017-11-06 05:27:58
【问题描述】:
这是我的java程序的描述:
这是一种在线程中运行数小时的优化算法, 经常被服务打断以查询有关 当前优化。
优化例程是一系列简单的操作(让我们 称之为“移动”),一遍又一遍地重复。有时, 优化过程会减慢很多:移动通常需要 不到100ms,有时甚至需要几秒钟 分钟。
当然我考虑过 GC 会在执行 full GC 时冻结执行,所以我做了一些实验,根据 GC 日志,minor 收集非常有规律,需要 10ms,而 full GC 非常罕见,不会超过 2 秒.我还通过 GC 日志分析工具进行了一些分析,吞吐量达到了 95% 以上。例如,在 7 分钟的测试运行中,根据 GC 日志,只有 2 到 3 秒的时间因 GC 而丢失。
应该得出结论,GC 不是这里的问题。但是,我观察到尝试其他 GC 算法会对“最差”动作所需的时间产生相当大的影响(当“动作”开始变慢时,它可以使“动作”的执行时间增加一倍/三倍)。因此,GC 似乎对其产生了影响,即使 GC 日志告诉我 GC 没有花费时间。
此外,我还观察到“动作”往往会按顺序减速:当一个动作减速时,下一个动作也有更大的减速机会,即使它们与这些操作没有任何关系是完全独立的。只是感觉整个系统有时会变慢,尤其是当服务被大量调用时。
我读到了一些关于堆空间内存碎片的内容,这些碎片可能导致应用程序严重减速,并且由于我的动作正在创建和销毁大量对象,这可以解释我在这里遇到的情况。但是,我不明白为什么 GC 日志不显示这一点。
我在这里真的达到了我的知识和经验的极限,我会采取任何直觉或线索,您可能需要进一步调查。
【问题讨论】:
-
性能是一大堆蠕虫。您还需要查看 JVM 周围的所有内容,而不仅仅是 GC。当你说你觉得“慢”时,你能分解一下从请求到响应的时间吗?网络时间是多少?处理时间?堆使用率,最重要的是 CPU%。经常进行压力测试,测试的是硬件而不是软件。当 CPU 利用率低于 80% 时,Java 表现良好。请提供更多统计数据,我很乐意进一步讨论。
-
一切都在同一台计算机上本地运行。 CPU 保持在 50% 以下,具体取决于机器。真正减慢的是“移动”操作。移动会创建项目的副本 (.clone()),对其应用修改(称为“移动”),并将其添加到具有有限大小(先进先出)的堆栈中。一个移动通常需要 10 到 100 毫秒,具体取决于移动,当它放慢速度时,可能会持续 1 秒到 1 分钟(最坏情况下为 10 分钟)。
-
堆大小是多少?你能发布你的运行时参数吗?
-
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -Xloggc:C:/temp/gc.log -Xmx3g
-
好的,你的 JVM 正在使用 CMS GC。运行测试时,您确实看到堆增加了吗?年轻代空间变化很大吗?使用 CMS 的缺点是当堆建立时,Full GC 将需要更长的时间来运行。您是否尝试过使用其他 GC?像 parallelOldGC 和 paralledGC?
标签: java performance memory-leaks garbage-collection jvm