首先要弄明白两个概念:内存泄露和内存溢出。
内存泄露是指垃圾没有被完全回收,就是有空间但是要不回来;
内存溢出则是空间根本不够用。
两者虽然不同但是可能导致相同的后果。
1、java.lang.OutOfMemoryError: Java heap space
这是最典型的内存泄漏方式,简单说就是所有堆空间都被无法回收的垃圾对象占满,虚拟机无法再在分配新空间。
这种方式解决一般是根据垃圾回收前后情况对比,同时根据对象引用情况(常见的集合对象引用)分析,基本都可以找到泄漏点。
2、java.lang.OutOfMemoryError: PermGen space
Perm空间被占满。无法为新的class分配存储空间而引发的异常。这个异常以前是没有的,但是在Java反射大量使用的今天这个异常比较常见了。主要原因就是大量动态反射生成的类不断被加载,最终导致Perm区被占满。
如何解决:设置 -XX:MaxPermSize=16m,或者换用JDK
3、java.lang.*Error
一般是递归没有找到出口,或者循环调用导致。
4、Fatal: Stack size too small
线程栈空间不够用,可以通过修改线程栈大小的方式来解决,比如设置-Xss2m。但这个配置无法解决根本问题,还要看代码部分是否有造成泄漏的部分。
5、java.lang.OutOfMemoryError: unable to create new native thread
这个异常是由于操作系统没有足够的资源来产生这个线程造成的。
解决方式:重新设计系统减少线程数量;线程数量不能减少的情况下,通过-Xss减小单个线程大小。以便能生产更多的线程。