是)我有的:
>具有1Gb RAM和1.4GHz处理器的VPS服务器(1Core)
> Ubuntu Server 12.04
> Java(TM)SE运行时环境(版本1.7.0_51-b13)
> Java HotSpot(TM)64位服务器VM(内置24.51-b03,混合模式)
> Glassfish v4.0运行我的Java EE webapp
> VM使用以下参数运行
-XX:MaxPermSize参数=200米
-XX:PermSize =百米
-XX:Xmx = 512m(我可以添加所有相关的)
问题是什么:
Ram使用(res内存)一直在增长,这取决于每小时10-100m的使用情况,直到jvm无法分配本机内存.
我试过了什么:
>我降低了最大堆空间,这只能节省时间,直到jvm崩溃为止
>我附加了plumbr(https://portal.plumbr.eu/),它没有检测到堆中的任何内存泄漏
>我还将最大烫发大小设置为较低的值.
我想让我的JVM保持稳定,因为我测量堆空间perm gen只需400-600 mb而“top”命令显示java进程内存增长直到850mb然后自杀.我知道JVM需要更多内存来烫发空间和堆,但你认为我还是给堆空间和perm gen留了太多内存吗?
任何帮助或指南将受到高度赞赏.
日志输出:http://pakers.lv/logs/hs_err_pid970.log
所有JVM flgas:http://pakers.lv/logs/jvm_flags.txt
更新
我还尝试了什么(基于建议和我自己的发现):
>我已经减少并修复了256m的堆空间,然后在系统仍然稳定的情况下使用了icreased,我注意到我能在系统上承受的最大堆是512m和128m perm gen space. (-Xmx512m,-Xms512m,-XX:PermSize = 128m,-XX:MaxPermSize = 128m)
>减少了java线程大小-Xss256k,我无法将其减少到小于218k(jvm won`t start)
>添加了-D64,以便jvm以64位模式运行
>添加-XX:AggressiveOpts(以启用性能优化),– XX:UseCompressedOops(以减少堆空间内存使用),– server标志以在服务器模式下启动jvm
>由于我的堆空间大小非常有限,我修改了NewRatio,使其有一个更大的tenured generation(堆空间的1/3)-XX:NewRatio = 3
>添加了GC的诊断选项,以便我可以检查OOM错误
-XX:PrintTenuringDistribution
-XX:PrintGCDetails
-XX:PrintGCTimeStamps
-XX:HeapDumpOnOutOfMemoryError
-Xloggc:/home/myuser/garbage.log
当前状态
通过这些更改,我最终限制了java进程的驻留内存(RAM使用率),这是我的目标.在我的情况下,512m堆空间128m perm gen空间导致大约750m的java进程驻留内存是稳定的.即使我仍然有内存问题 – 堆内存不时充满并导致Web应用程序因持续垃圾回收而冻结,但操作系统不会终止进程.所以我现在需要增加系统的可用内存(RAM)或检查堆使用情况并降低应用程序的占用空间.由于我的webapp是基于Java EE的(使用EJB),我可能无法显着减少它.无论如何,感谢您的建议,并随时分享任何其他建议.
>泄漏的JNI库,或者,
>线程创建泄漏,或
>泄漏动态代码代理(perm-gen leak),
但我只能猜测,因为你没有提供任何日志输出,或者指出JVM是否抛出OutOfMemoryException(OOM),或者是否遇到其他一些错误.您也没有提到垃圾收集器正在使用中,但如果上面显示的标志是唯一使用的JVM选项,那么它就是CMS收集器.
-XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -Xloggc:/path/to/garbage.log
如果它确实是一个OOM,那么您可以使用VisualVM或类似工具分析堆转储.我还使用VisualVM通过JMX原位监视GC操作.可以通过以下JVM标志启用对JVM内部通道的可见性:
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=4231 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
其他资源:
> http://www.oracle.com/technetwork/java/javase/memleaks-137499.html
> http://javabook.compuware.com/content/memory/problem-patterns/memory-leaks.aspx
> https://visualvm.java.net/heapdump.html
> http://www.marcsturlese.com/2009/05/09/analyzing-java-heaps-with-jmap-and-jhat/
更新
日志确实有帮助.谢谢.该特定日志显示它在物理内存耗尽之前可以将堆增长到配置的最大值.它尝试了malloc~77M并且只有~63M物理左:
Native memory allocation (malloc) Failed to allocate 77873152 bytes for committing reserved memory.
..
/proc/meminfo:
MemTotal: 1018724 kB
MemFree: 63048 kB
这就是我要做的事情:
>减少堆,使其“适合”在机器上.将min和max堆设置为相同的值
你可以判断它是否适合立即 – 它不会启动它
不合适.
>你可以减少Java堆栈大小(-Xss),但这件事
似乎没有做出很多线程所以节省
不会超过一两个Mb.我认为64位Linux的默认值是256k.减少太多,它将开始堆栈分配上的OOM.
>重复测试.
>当它在负载下运行一段时间后,产生一个
用于差异诊断的按需堆转储
jmap -dump:file = path_to_file< pid>.
>应该发生以下两件事之一:(a)如果发生泄漏,最终会再次失败,
但是OOM的类型应该是不同的,或者(b)没有泄漏,这样GC就会发生
只是努力工作,你就完成了.鉴于您之前尝试过,前一种情况很可能,除非您缩小的最大尺寸也不合适.
>如果它是OOM,请比较两个转储以查看使用jhat或其他堆分析器增长的内容.
祝好运!