在最初自学Java的时候就听过GC的大名,但是以为只是一个普通的机制,现在从头学起来发现学问还是很深的,不得不说Java真强大
在JVM体系中,堆内存是内存数据区,用来保存运行时的对象实例。垃圾回收器也是在此进行工作的。在运行时,Java的实例被封存在对内存区域,当一个对象不再被引用时,满足条件就会从对内存移除,在垃圾回收进程中,这些对象将会从对内存移除并且内存空间会被回收,JVM垃圾回收器结构:
如果在两个收集器之间存在连线则说明他们可以搭配使用,虚拟机所处的趋于则表示它是属于新生代还是老年代收集器。G1则是整堆收集器。
作为一个自动的过程,程序员不需要在代码中显示的启动垃圾回收器,system.gc()和Runtime.gc()用来请求垃圾回收,虽然程序员可以启动GC但是启动由JVM负责,JVM可以拒绝这个请求,启动的时机由JVM决定,并且取决于堆内存中Eden区是否可用。
以下是两种基础的回收算法
1.1引用计数算法
有点类似OS中文件管理的软链接,给对象添加一个引用计数器,每当一个地方引用它时计数器+1,当引用失效时计数器-1,只要计数器等于0的对象就是不可能再使用的。改算法的优点是实现简单,判断效率高。缺点是没办法解决对象之间的循环问题,
1.2可达性分析算法
有点类似使用深度优先遍历求图的连通分量,即通过一系列的称为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路经称为引用链,当一个对象到GC Roots没有使用任何引用链时,中文说明该对象是不可用的。主流语言如Java c#都是通过可达性分析来判定对象是否存活
5、6、7均是可回收对象。
该方法的优点是更加严谨,但是实现较复杂,需要分析大量数据,消耗大量时间,分析过程需要GC停顿(引用关系不能再发生变化)称为STW(stop the world)
部分参考: