我正在运行嵌入了Jetty服务器的应用程序。应用程序正在慢慢消耗更多内存,因为堆大小根本没有变化。
这是启动应用程序的命令:
java -server -Xms1G -Xmx1G -Dfile.encoding = UTF-8
这是来自新遗物的图表,其中RAM使用率增加 它开始使用1140MB,8小时后完成1290MB
有什么建议吗?
[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
现在将继续监控...
答案 0 :(得分:1)
经过多次不同类型的调查后,我回到.net-4.0并再次尝试......
但这一次我决定相信泄密报告说:
加载的“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();