目录
这篇日志总结下Java程序中的发生内存溢出的一些原因,我们知道JVM堆空间十分重要,大部分对象在创建时都是放在堆中(除了一些逃逸对象是栈上分配),例如新生代存放在eden区中。随着对象的不断创建和老年代对象的不断产生,如果垃圾回收不能及时释放内存,最终堆内存被耗尽,新对象创建时由于内存不足,申请空间失败,导致内存溢出,在Java程序中内存溢出分几种,直接内存溢出,堆溢出和永久区溢出,在总结这几种内存溢出情况前,先分清内存溢出和内存泄漏这两者的区别和关联。
内存溢出和内存泄漏
内存泄漏(memory leak)指的是程序执行过程中,在申请内存,使用完毕后没有释放资源,内存堆积越来越多,最后堆空间被占用完,内存泄漏大致可以分为4种:
- 一次性内存泄漏:指的是由于逻辑实现部分的问题,该部分代码只会被执行一次,但一执行就会有一片内存发生泄漏。
- 常发性内存泄漏:指的是这部分代码会被执行多次,每一次执行时都会导致一片内存发生泄漏。
- 偶然性内存泄漏:指的是这部分代码在某些特定场合下执行才会发生泄漏,这类情况比较难发现。
- 最后一种是隐式的内存泄漏:指的是对于一些需要运行很久的程序,例如服务器程序,程序运行过程种不断地申请内存,一直到程序运行结束后才把所有的空间释放掉,如果中途GC没有及时回收可用空间,最总也会导致内存泄漏,当然也有可能程序运行到结束后也没有出现泄漏,这样的情况称为隐式内存泄漏,泄漏有可能发生,也可能不发生。
内存溢出上面讲了是怎么一回事,就是没有足够的空间分配给新的对象了,内存泄漏与溢出两者的关系,就是内存泄漏最后会导致内存溢出。