概念
为了避免内存溢出,内存泄漏的问题,虽然java有自动垃圾回收机制,但是在高数据量,高并发时,我们仍需要去注意java的回收机制。
引用
Java回收算法需要判断对象是否存活,判断存活的方式,都与“引用”有关,引用的含义是指:引用类型的数据中,存在其他对象的内存地址,我们称这块内存存在引用。java中将引用分为四个强度等级:
- 强引用 ,java中最普遍存在的引用方式,只要强引用还存在,虚拟机宁可报出“OOM”异常,也不会对强引用进行回收;
- 软引用 ,指的是有用但是非必需的对象。当内存快要满的时候,虚拟机会对软引用对象进行回收,如果回收后内存空间还是不够,就会报出“OOM”异常,java中使用SoftReference类来实现软引用;
- 弱引用,用来指非必需对象,引用强度要小于软引用 ,只要虚拟机扫到弱引用,就会对该对象进行回收,java中使用WeakReference类来实现弱引用。
- 虚引用,最弱的引用方式,(使用的目的是为了得到系统回收时的一个通知)。java中使用PhantomReference来实现虚引用;
回收算法
引用计数法
该方法通过给对象添加一个引用计数器,每当对象被引用时,计数+1,取消引用时,计数-1,当计数等于0时,代表对象不可能再被使用了,比如python目前再用引用计数法来管理内存。
这里存在一个问题,如果对象之间相互存在引用,当两个对象不在被使用时,如果两个对象相互牵着彼此,两个对象的计数都不为0,计数器就不会通知虚拟机来回收对象。所以引用计数法不是当前java虚拟机中用的管理内存的方法。
可达性分析算法
从GC Roots 出发,当对象与GC Roots存在引用链时,系统就不会将其回收。这是目前Java 虚拟机最主流的内存管理方式。
java中一般会将以下几种作为GC Roots:
1.虚拟机栈中的对象
2.本地方法中的对象
3.方法区中的常量对象
4.静态属性对象