JVM内存
内存泄露:是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
GC机制
既然java有垃圾回收(GC)机制,理论上不应该有内存泄露的问题,然而总会有无用但可达的对象,这些对象不能被GC回收,因此也会导致内存泄露的发生。
例如: hibernate的Session(一级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然而这些对象可能存在无用的垃圾对象,如果不及时关闭或者清空一级缓存可能会导致内存泄露
注:栈的pop方法调用,即使栈的程序不再引用这些对象,因为栈内部维护着这些对象的过期引用,所以该不会被当做垃圾回收。这种内存泄露是隐蔽的,垃圾回收机制同时也不会回收内存泄露对象所引用的对象。因此会导致很多对象都排除在垃圾回收之外,从而对性能产生重大的影响
Java中为什么要有GC机制
- 安全性考虑
- 减少内存泄露
- 减少程序员的工作量
Java的GC需要回收那些缓存
内存运行时,JVM会有一个运行时数据区来管理内存,包括:
- 程序计数器
- 虚拟机栈
- 本地方法栈
- 方法区
- 堆
程序计数器、虚拟机栈、本地方法栈都是每个线程私有的内存空间,随着线程而生,随线程而死。这三个区域的内存分配和回收都是确定的,无序考虑回收的问题,但是方法区和堆就不同了,一个接口的多个实现类需要的内存可能不一样。我们只有在程序运行期间才会知道会创建哪些对象,这部分内存的分配和回收都是动态的,GC主要关注的就是这部分内存
内存溢出的原因很多,简单举几个:
- 内存中加载的数据量过于庞大,如一次从数据库中取出过多数据
- 集合类中有对对象的引用,使用完没有情况,使JVM不能回收
- 代码中存在死循环或者代码中产生过多重复的对象实体