《带你走进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(内存泄漏)是指程序中已被分配的堆内存由于某种原因导致无法释放,从而造成内存的浪费。