带有jetty内存泄漏问题的java服务器

时间:2016-02-26 16:23:41

标签: java memory-leaks server jetty

我正在运行嵌入了Jetty服务器的应用程序。应用程序正在慢慢消耗更多内存,因为堆大小根本没有变化。

这是启动应用程序的命令:

java -server -Xms1G -Xmx1G -Dfile.encoding = UTF-8

这是来自新遗物的图表,其中RAM使用率增加 enter image description here 它开始使用1140MB,8小时后完成1290MB

这是堆的jvisualvm图表。 enter image description here

有什么建议吗?

[EDIT1] 添加转储https://www.dropbox.com/s/1gt1i9dhjtjauf0/gameserver-20160226-2107.zip?dl=0

[EDIT2] 以下是我目前调查的一些注意事项

=如何监视堆外的内存 添加参数

-XX:NativeMemoryTracking=detail -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics

运行命令 jcmd 3322 VM.native_memory摘要 @see https://devcenter.heroku.com/articles/java-memory-issues

=检查默认的线程堆栈大小 java -XX:+ PrintFlagsFinal -version | grep ThreadStackSize

  
    

intx ThreadStackSize = 1024
    How to reclaim the memory used by a Java thread stack?

  

=了解最大内存 最大内存= [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss] @see https://plumbr.eu/blog/memory-leaks/why-does-my-java-process-consume-more-memory-than-xmx

=行动 减小线程堆栈的大小。 (理论上,你可以低至64K ......)

-XX:ThreadStackSize=256

降低GC后堆的最小自由百分比,以避免扩展。

-XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=10

现在将继续监控...

1 个答案:

答案 0 :(得分:1)

经过多次不同类型的调查后,我回到并再次尝试......

但这一次我决定相信泄密报告说:

  

加载的“org.hibernate.internal.SessionFactoryImpl”的一个实例   “sun.misc.Launcher $ AppClassLoader @ 0xc001d4f8”占据2.956.808   (21,05%)字节。内存在一个实例中累积   “org.hibernate.internal.SessionFactoryImpl”加载   “sun.misc.Launcher $ AppClassLoader @ 0xc001d4f8”。

然后我将调查转移到我的DAO实现,期望我忘记关闭一个或其他EntityManager调用。情况并非如此,所有这些都是在使用后使用了一个很好的close()方法调用。

然后我意识到问题可能在于hibernate本身,因为有问题的对象是 SessionFactory Impl,所以我每次创建实体管理器时都改变了我的DAO实现以清除Hibernate第一级缓存,因为我无法找到一种方法来禁用它。

一天的结果= IT工作!! :)记忆改变了痘痘并在几分钟后回来,但不再以疯狂的方式成长(24小时内1000MB)。

这是我改变的代码,希望它可以帮助某人。

public EntityManager getEntityManager(){
    if( emf == null ){
        if (parameters == null) {
            emf = Persistence.createEntityManagerFactory(persistenceUnitName);
        } else {
            emf = Persistence.createEntityManagerFactory(persistenceUnitName, parameters);
        }
    } else {
        emf.getCache().evictAll();
    }

    EntityManager em = emf.createEntityManager();
    return em;
}

关键在于: emf.getCache()。evictAll();