新手阅读本文之前请先了解以下概念,如果是老鸟,请直接跳过本环节
1.什么是垃圾?
简单点说就是没有引用指向的内容。
2.垃圾存在在什么地方?
程序运行在内存中,如果把内存容量本身看成一个五子棋棋盘,就有了下面的说明。
3.什么时候会产生垃圾,什么时候会清理垃圾?
内存容量想成一个棋盘,程序本身像是已经在棋盘上面按照规律排列的同色棋子。程序会占用棋盘中的一部分体积。
程序不断运行,产生的内容就等于往棋盘中不断的加入棋子。垃圾就像是一些不同色的棋子。
当不同色棋子的体积总量慢慢变大,达到一定数量或者说某个阈值,就会触发垃圾回收。也就是清理垃圾的环节。
4.谁来清理垃圾?
接着上面的木桶来说,清理垃圾的程序就好像是在棋盘旁边下棋的人,这个人不眠不休,等着清理棋子
看完上面的内容,相信你已经对JVM的垃圾回收机制有了一个最基本的理解,那么接下来需要说明的是一些算法和理论知识。这些知识并不难理解,但是需要好好看
当然在进行垃圾清理之前需要先找到并标记垃圾,那么就有了下面的两种处理方式:
如何找到垃圾?
算法1:reference count,引用计数
只要没有指针指向这个对象,那就是垃圾
弊端:无法解决循环引用问题
算法2:Root Searching 根可达算法
根:线程操作数栈,静态变量,常量池,JNI指针(调用C/C++)
根据根去找垃圾
找到垃圾之后,就需要进行清理垃圾,清理垃圾有以下三种算法:
常见的垃圾清理算法
1.Mark-Sweep 标记清除
需要先标记再清除,两遍扫描;
- 第一遍:先找到可回收的,找到不可回收的
- 第二遍:清除可回收的垃圾
清除效率偏低,但是在存活对象较多的情况下,清除效率较高。容易产生碎片
2.拷贝算法
将内存分为两块,将存活的对象复制到第二块区域,然后清除第一块区域
适用于存活对象较少的情况,效率较高,没有碎片
空间浪费,且移动对象时需要注意对象引用的变化
3.标记压缩
先标记对象是否为可回收的,再进行清除,清除之后将对象挪动位置
- 扫描两遍,对象位置移动,效率较低
- 不会产生碎片,不会导致内存减半,方便对象分配
以上就是本篇博客的所有内容,第一次发表博客,轻喷。
如有错误,欢迎指正。