JVM内存泄漏分析

问题

Java线程是JVM基础的一部分。你的Java堆空间内存占用不仅仅是由于静态对象和长生命的对象导致,还有可能因为短生命对象。
OutOfMemoryError问题经常被误认为是内存泄露引起。我们经常忽略错误的线程执行模型和它们持有的JVM里的短生命对象,直到它们的执行完成我们才发现。
在这种问题情形下:

  • 程序中短生命/无状态对象(XML,JSON数据负载等)被线程持有的时间会变得很长(线程锁争用,大量数据负载,远程系统的慢响应时间等)。
  • 这种短生命对象会因为垃圾收集而晋升到长生命空间,比如老年代空间。
  • 副作用是会导致老年代空间很快被占满,增加了Full GC(major收集)的频率。
  • 由于这种严重的情况,它将导致更多的GC垃圾收集,增加JVM暂停时间和最终的OutOfMemoryError:Java堆空间。

你的应用此时被停掉,你很疑惑到底怎么回事。最后,你考虑增加Java堆空间或者寻找哪里有内存泄露,你真的找对路了么?
避免在线程栈大小(虚拟机栈)和Java堆内存占用之间产生混淆是非常重要的。线程栈(虚拟机栈)大小是一种特殊的内存空间,它被JVM用于存储每个方法调用。当一个线程调用方法A,它将这个调用入栈。如果方法A调用方法B,同样也会入栈。一旦方法执行完毕,这个调用便从栈里出栈。
这种线程方法调用会导致Java对象产生,并分配在Java堆里。增加线程栈的大小是没有任何效果的(对象最终在堆得年轻代(Eden)产生)。而调整线程栈大小通常是要处理java.lang.stackoverflowerror错误或者OutOfMemoryError: unable to create new native thread错误的时候才会需要。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×