《带你走进Java的世界》第九章相关学习笔记

更高效地使用内存

STW、栈溢出、内存溢出

Stop the World

当虚拟机判断有必要进行垃圾回收,而且程序运行到“安全点”时,就会暂停所有运行的线程(Stop the World),只启动垃圾回收线程来进行回收工作。

栈溢出

代码中出现线程或方法的递归调用,会导致栈中的帧数增多,如果栈中所有栈帧的大小超过Xss参数的设置,就会产生StackOverflowError(栈溢出错误)。
因此建议,在代码里尽量避免递归,如果无法避免,尽量控制递归的深度

内存溢出

OutOfMemoryError(内存溢出错误),最恶心的问题,OOM的后果比较严重且无法重现,导致无法定位和修复,归纳下可能导致OOM出现的原因:

报出的异常 原因 常规解决方法
java.lang.OutOfMemoryError: unable to create new native thread
无法创建线程
当通过new Thread等方法无法创建线程时,则会抛出此错误。
创建不了的原因通常是线程太多耗尽了内存。
1 可在代码里减少线程数。
2可通过-Xss调小线程所占用的栈大小,从而降低对内存的消耗。
java.lang.OutOfMemoryError: Java heap space
堆内存溢出
这种是最常见的,当通过new创建对象时,如堆空间不足,触发轻量级 GC和Full GC依然不够,则会抛出此错误。 没有固定的解决方法,只能检查程序,看哪些对象没有被及时回收。如果线上遇到了OOM,该如何解决?
java.lang.OutOfMemoryError: GC overhead limit execeeded 当通过new创建对象时,如堆空间不足,且垃圾回收所使用的时间占了程序总时间的98%,且堆剩余空间小于2%,则抛出此错误。 可通过UseGCOverheadLimit来决定是否开启这种策略,如果出现这类问题,也应检查哪些对象可以被及时回收,从而提升内存使用性能。
java.lang.OutOfMemoryError: PermGen space 当类加载器加载class时,如持久区空间不足,则抛出此错误。 可以通过-XX:MaxPermSize,调高持久区的最大值。

内存泄漏示例

Memory Leak(内存泄漏)是指程序中已被分配的堆内存由于某种原因导致无法释放,从而造成内存的浪费。

优化内存性能具体做法

调整运行参数,优化堆内存性能

定位和排查内存性能问题

定位和排查内存性能问题

什么情况下该排查性能问题

通过JConsole监控内存使用量