共计 2059 个字符,预计需要花费 6 分钟才能阅读完成。
既然抉择了远方,即便天寒地冻,路遥马亡,我本就赤贫如洗,又有何惧。
OOM(内存溢出)是一个让人很头疼的问题,呈现 OOM 的问题有很多,上面就 OOM 可能呈现的起因进行介绍。
1、堆空间太小
用以下参数启动 jvm
-Xms20m -Xmx20m
public class OOMTest {public static void main(String[] args) {Byte[] bs = new Byte[1024 * 1024 * 30];
}
}
最大堆、初始化堆均为 20m,程序创立了 30m 的数组,间接 OOM。
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
1.1、解决形式
- 调大
-Xmx
的值 - 通过内存剖析工具,找出占用内存较多的对象
2、间接内存溢出
间接内存属于堆外内存,是间接向操作系统申请内存空间。
间接内存申请速度个别小于堆内存的申请速度,然而访问速度会比堆内存的访问速度快。
间接内存并没有齐全的归 GC
治理,使用不当,也会造成 OOM
。
2.1、间接内存不足,溢出
用以下参数启动 jvm
-Xms20m -Xmx20m
public class OOMTest {public static void main(String[] args) {while (true) {ByteBuffer.allocateDirect(1024 * 1024 * 30);
}
}
}
间接内存最大值为 20m, 所以间接溢出
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:694)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at com.csp.boot.jvm.OOMTest.main(OOMTest.java:14)
注:间接内存最大值,默认为 -Xmx
配置的值
2.2、解决形式
- 调小
-Xmx
的值,让操作系统有更多的内存调配给间接内存 - 防止一次性调配太大的间接内存
- 设置正当的
-XX:MaxDirectMemorySize
2.3、间接内存回收
间接内存只有在使用量触到 -XX:MaxDirectMemorySize
时,才会触发 GC
,具体看上面 demo
用以下参数启动 jvm
-Xms20m -Xmx20m -verbose:gc
public class OOMTest {public static void main(String[] args) {while (true) {ByteBuffer.allocateDirect(1024 * 1024 * 1);
}
}
}
启动后,会在程序控制台,看到有 GC 日志一直的输入
[GC (System.gc()) 2474K->731K(19968K), 0.0016716 secs]
[Full GC (System.gc()) 731K->631K(19968K), 0.0043987 secs]
3、线程过多
在 java 内存模式中, 虚拟机栈,本地办法栈,程序计算器 这些都是线程独有的,线程自身也占用内存空间,如果线程启用太多,会间接导致 OOM
用以下参数启动 jvm
-Xms20m -Xmx20m
public class OOMTest {public static void main(String[] args) {while (true) {new Thread(() -> {
try {Thread.sleep(30000);
} catch (InterruptedException e) {e.printStackTrace();
}
}).start();}
}
}
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:717)
at com.csp.boot.jvm.OOMTest.main(OOMTest.java:19)
3.1、解决形式
- 适当调低
-Xss
的值,可使jvm
创立更多的线程
4、GC 效率低下
当 GC 效率低下时,也会呈现 oom
。GC 效率低下导致的 oom
条件刻薄,然而还是不可避免会呈现
4.1、触发条件
- 花在 GC 的工夫上,超过 98%
- 老年代开释的内存小于 2%
- 新生代开释的内存小于 2%
- 间断 5 次 GC 都呈现以上状况
触发后,会抛出以下异样
注:必须满足以上所有条件,才会触发
5、内存泄露
呈现内存泄露的起因,次要是对象曾经无用了,然而却无奈被回收。从而可应用的内存越来越少,最终触发 OOM
.
找出内存泄露的罪魁祸首个别须要借助内存剖析工具,进行剖析。这一部分的内容比拟多,会放到下一章节来说。