0

我们使用的是 2.1.7,偶尔会在客户端应用程序和 OrientDB 服务器中出现 OutOfMemory(每两个月一次)。所以我们最近将 OrientDB 从 2.1.7 升级到了 2.2.11。升级后,我在一天之内就在从 OrientDB 查询数据的客户端应用程序中获得了 OutOfMemory。

在堆转储中,有17,014个OSBTreeCollectionManagerRemoteOStorageRemoteAsynchEventListener实例,它对应于总内存的 95%。

内存问题嫌疑人截图

作为升级的一部分,Java 也升级到了 8。

客户端(tomcat)JVM参数:

-Xmx2048m -XX:MaxPermSize=512m -XX:MaxDirectMemorySize=2048m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:+CMSClassUnloadingEnabled 

我试过有无图连接池,结果是一样的。

谁能提供有关如何解决此问题的更多信息。如果有人感兴趣,我可以分享堆转储。

4

1 回答 1

1


您正在使用吞吐量收集器 (ParallelGC),并且您还启用了 ParallelOld,因此-XX:+CMSClassUnloadingEnabled未使用(因为这是与 ConcurrentMarkSweep 收集器一起使用的标志,用于在运行简单 CMS 阶段时从永久/元空间卸载类,而不是等待不需要的FullGC)

请描述您的客户端机器,哪个操作系统,多少可用内存,多少cpu /核心,客户端机器上正在运行多少java进程?
请记住,永远不要换出 java。

与其收集大量静态堆转储列表,不如从收集器的动态行为跟踪开始,使用 PrintGC 选项,如果您怀疑存在泄漏,请使用 jmap -histo:live 检查增加的打印 ascii 直方图的实例数量(在收集直方图之前执行 FullGC)

ParallelGC 在老年代使用 Full GC,所以这是预期的行为。

你会得到哪个 OutOfMemory ?它是堆中的还是永久的还是直接的?我想在堆中,因为你的标志。

尝试了解哪个段已满,并将其增加到您的客户端机器的限制;要生成带有进程号和时间戳的 gc.log,请使用:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gclog_%p_%t.log

您还可以添加-XX:+PrintTenuringDistribution, to see if promotion is done too early, when age of objects is too low. It could be that new size is too small, so should use a bigger new generation with -Xmn

您还可以使用 来了解每个 XX 标志的当前值-XX:+PrintFlagsFinal。另请参阅http://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html

使用当前代大小启动 java 8u102,并在需要时增加它们:

-Xms2048m -Xmn768m -Xmx2048m -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:MaxDirectMemorySize=2048m -XX:+UseParallelOldGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -Xloggc:$CATALINA_HOME/logs/gclog_%p_%t.log <br><br>
<br>
For java 7, instead of Metaspace use Permanent: -XX:PermSize=512m -XX:MaxPermSize=512m

如果您需要反馈,请提供有关客户端机器和 gclog 的所有信息。

如果您自己从 gclog 进行一些调整,并且您将似乎太小的内存段增加了几倍,但您仍然获得相同的 OutOfMemory,那么您的应用程序中可能存在内存泄漏,因为 ParallelGC 与 FullGC 一起使用(所以应该清理所有释放的对象/类/字符串)

于 2016-10-11T08:52:53.433 回答