有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在运行这个嵌入Jetty服务器的应用程序。应用程序正在缓慢地消耗更多内存,尽管堆大小根本没有改变

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

java-server-Xms1G-Xmx1G-Dfile。编码=UTF-8

这是NewRelic随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

[编辑二] 以下是我目前调查的一些记录

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

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

运行命令 jcmd 3322虚拟机。本机内存摘要 @见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]+线程数*[-Xss] @见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) 个答案

  1. # 1 楼答案

    经过大量不同类型的调查,我回到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()。逐出所有()