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

标签 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

有什么建议吗?

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

[编辑2] 这是我当前调查的一些笔记

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

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

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

= 检查默认线程堆栈大小 java -XX:+PrintFlagsFinal -版本 | grep 线程堆栈大小

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

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

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

-XX:ThreadStackSize=256

在 GC 后降低最小堆空闲百分比以避免扩展。

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

现在会继续监测...

最佳答案

经过大量不同类型的调查,我回到了 Eclipse Memory analyzer并再次尝试......

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

One instance of "org.hibernate.internal.SessionFactoryImpl" loaded by "sun.misc.Launcher$AppClassLoader @ 0xc001d4f8" occupies 2.956.808 (21,05%) bytes. The memory is accumulated in one instance of "org.hibernate.internal.SessionFactoryImpl" loaded by "sun.misc.Launcher$AppClassLoader @ 0xc001d4f8".

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

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

一天结束的结果 = 成功了!! :) 内存变化了一点,几分钟后又恢复了,但不再以疯狂的方式增长(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();

关于具有 jetty 内存泄漏问题的java服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35656798/

相关文章:

java - SocketException - 'Socket is closed' 即使 isConnected() 返回 true

c - 调试时使用 exit() 函数

python-3.x - Kotlin TCP套接字客户端无法正常工作的Python服务器

apache - Tomcat Apache 服务器重启要求过于频繁

java - 操作不同 Jpanel 中的按钮

java - 创建 ObjectInputStream 时线程挂起

c - SQLite3 中的内存泄漏

iOS内存泄漏与 Nib

java - 关闭tomcat 8并启动tomcat 9

java - 如何在 Windows 7 上运行 Play 框架