垃圾回收主要针对的是JVM的堆内存,分为新生代和老年代。
![](https://i-blog.csdnimg.cn/blog_migrate/5349fc2eb51e05596e63b40646d85414.png)
按照以前的叫法,还有一个永久代,它在方法区里保存了class信息、静态变量、常量池等。
![](https://i-blog.csdnimg.cn/blog_migrate/475ea152309185dc11cbfc03629ff6ce.png)
![](https://i-blog.csdnimg.cn/blog_migrate/54db663a15ee927adcde9e1dad00b2da.png)
这样会使得内存溢出的可能性进一步减小,空间大小变得更容易扩展。
与此同时,方法区也将一部分数据转移了出去,比如类的静态变量、字符串常量池等都放到了堆内存当中。这个变化从1.8后正式开始。
![](https://i-blog.csdnimg.cn/blog_migrate/52f75992a700fea854be7bc888cc6d10.png)
我们平时所讨论的JVM,都是Hopspot版本。刚才提到的永久代,是Hopspot特有的。
在堆内存中,从垃圾回收的范围上说,一般分为两种,新生代的垃圾回收叫Young GC,老年代的垃圾回收通常伴随着新生代的垃圾回收,叫做Full GC。
对垃圾的处理分为搜集算法和回收算法。
垃圾搜集算法
首先需要标记出需要回收的对象,也就是要确定哪些是垃圾。有两种方法,一种叫引用计数法,另一种叫做可达性分析算法。
引用计数法
每个对象都会有一个引用计数器,每当有一个引用指向这个对象的时候,对象的计数器就+1,这样的话,只要观察这个对象的引用计数器,数值>0,就表示还有人在使用,这个对象就不能回收。
![](https://i-blog.csdnimg.cn/blog_migrate/6b6d00b17ccbea94153e7dfeb75ba4a4.png)
当引用计数器=0时,表示没有任何引用指向这个对象,该对象已经不可访问,那么垃圾搜集器就可以回收它。
![](https://i-blog.csdnimg.cn/blog_migrate/9d894b868bc966f8f775a394c4e7f769.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e151f5b9ae86e8d1dedd8c8b1fd476b6.png)
可达性分析算法
因此,Java使用了一种叫做可达性分析的算法,就是从整个堆内存的根对象出发,看看有多少对象是可达的,有多少是不可达的,无法到达的也就意味着无法访问,自然就是垃圾了。
![](https://i-blog.csdnimg.cn/blog_migrate/93c9e235f5d9d7ecb3566bd28645a398.png)
- 栈中引用的对象(栈)
- 类静态属性引用的对象(方法区)
- 常量引用的对象(方法区)
- native方法引用的对象(本地方法栈)
垃圾回收算法
标记好垃圾之后,就可以回收了,下面介绍3种回收的算法。
标记-清除法
当垃圾回收器将内存扫描之后,会标记出所有垃圾对象,然后将他们回收。
![](https://i-blog.csdnimg.cn/blog_migrate/9a58134c99df630d790474bfe45c3d5e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1399f06d2a14a1f7af84d538363d8806.png)
标记-整理法
在清理垃圾的基础上,多了一步碎片整理的工作。
![](https://i-blog.csdnimg.cn/blog_migrate/a12c2b330d71ef9b6dfb74496dd5be95.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1f0477b42f70004ab77ce17f3c2769d0.png)
复制算法
准备两块一模一样的内存,当第一块内存空间不足时,将所有需要保留的对象拷贝至另一块内存。
![](https://i-blog.csdnimg.cn/blog_migrate/4f41d8a2363ae6ea833c2f50a6328fc4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8214af4de4897c6b49574f83d2a28b7b.png)
然后将前一块内存直接清空。
![](https://i-blog.csdnimg.cn/blog_migrate/3b7d26d6f0ac6bdd653788b108659d3b.png)
缺点:内存空间浪费一倍