1.java堆溢出
java堆用来存储实例对象,当对象数量到达最大堆的容量限制后就会产生内存溢出异常,可通过设置堆的最小值(-Xms参数)与堆的最大值参数(-Xmx参数)设置为一样可避免堆的自动扩展。
可通过参数-XX:+HeadDumpOnOutOfMemoryError让虚拟机内存溢出时Dump出当前的内存堆转储快照以便事后进行分析
当出现java堆内存溢出时,异常堆栈信息“java.lang.OutOfMemoryError”会进一步提示“Java heap space”
2.虚拟机栈和本地方法栈溢出
由于在HotSpot虚拟机中并不区分虚拟机栈和本地方法栈,栈容量只由-Xss参数设置。关于栈,在Java虚拟机规范中描述了两种异常:
1):线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常
2):虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常
3.方法区和运行时常量池溢出
运行时常量池溢出,在OutOfMemoryError后面跟随PermGen space,可通过-XX:PermSize和-XX:MaxPermSize限制调整方法区大小,可用String.intern()来给常量池增加常量。
如Spring、Hibernate,在对类进行增强时,都会使用到CGLib这类字节码技术,增强的类越多,就需要越大的方法区来保证动态生成的Class可以加载入内存,如果内存不够则会抛出PermGen space内存溢出异常。
String.intern():如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,且返回这个String的引用
CGLib:是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口
4.本机直接内存溢出
DirectMemory容量可通过-XX:MaxDirectMemorySize指定,如果不指定,则默认与java堆的最大值-Xmx一样
由DirectMemory导致的内存溢出,一个明显的特征是在Head Dump文件中不会看到明显的异常。如果发现Dump文件很小而程序中又直接或间接的使用了NIO,就有可能是这方面问题。