最近发现有些东西看过很久就是会忘记的,所以得在学习的时候加点什么动作加深一下记忆,所以到这里来浪费点时间,我会尽量放快点,这样不管是写的人还是看的人都会很省时间。
学过Android的人都知道,JAVA语言的基础知识是需要自己恶补的,通常你为了完成任务对一些很基础的知识只是有映像,但是你哪有时间把他详细的掌握清楚?JVM的垃圾回收问题就是其中最重要的基础问题之一。下面我主要从三个方面讲清楚这件事情:
- 哪些垃圾是需要回收的
- 有哪些重要的垃圾回收算法(答案是有三种,别纠结了)
- 垃圾回收的具体流程是怎样的
问题一: 哪些是需要回收的?
引用计数算法
JAVA中创建了一个对象,被引用一次加一,删除对该对象的引用就减一,引用计数为零时就需要被回收。
实在记不住的话想想你的钱包,挣钱了钱包装起来保管好,没钱了就去把他丢掉(说好听点:回收)。
可达性算法
可达性算法,首先要确定一系列的根对象(GC Roots),并从跟对象的起点根据对象之间的引用关系,搜索出一条引用链(Reference Chain),在引用链的对象就存活,而不在引用链的对象就认定为可回收对象。
实在记不住的话栓条狗去大街上遛,狗还被绳子牵着说明狗还活着,狗没被绳子牵着说明狗闯祸了,回收了吧。
- 根对象: 虚拟机栈中引用的对象,方法区中类静态属性引用的对象(static关键字声明的字段),方法区中常量引用对象(final关键字声明的字段),本地方法栈中引用的对象(native方法),JAVA虚拟机的内部引用(系统内部的东西当然能作为根了)
问题二:有哪些重要的垃圾回收算法?
(引子)标记-清除算法:
先标记后清除,是垃圾就标记出来,丢了。这不是傻子都会?需要注意的是:所谓的清除,并不需要真正地把整个内存的字节进行清零操作,只需要把空闲对象的起始结束地址记录下来放入空闲列表里,表示这段内存是空闲的就行。
- 优点: 简单,速度快
- 缺点: 执行效率不稳定,内存碎片化,最后无法分配大块的区域,乱麻???
那么下面两种算法就是对他的改进了。
记忆关键词: 标记,碎片化
标记整理算法
十分粗暴,主要针对两个缺点中的碎片化的问题,每做完一次大规模的删除产生很多的空隙之后,让所有存活的对象都向内存空间一端移动,然后清除到边界以外的内存。效率很低,不知道这实用性强不强,纠结这个还不如去看小猪佩奇。
记忆关键词:粗暴,全部向一端移动
标记复制算法
他将内存空间分为两块,在垃圾回收时将正在使用的内存中的存活对象复制到未被使用的内存块中,然后呢再清除正在使用的内存块中的所有对象。注意这里易位只是简单的改变指针,并没有在进行任何复制什么的操作,有些小伙伴会受图的误解。
很明显和上一中算法一样也需要对所有存活标记进行复制,还需要双倍空间,但是效率提高了,不得不说小猪佩奇没白看
记忆关键词:粗暴,开辟双倍空间
问题三:垃圾回收究竟怎样做?
既然说JVM虚拟机不会单独采用某种算法,而是会结合三种算法让他们协同工作,其具体的实现就是java虚拟机里的分代垃圾回收机制。
具体到JVM虚拟机中,内存的分配是这样的:
下面我简单讲一下这些对象的一生:
- 首先对象被创建出来快乐的生长在伊甸园,但是总有一天伊甸园都被挤满了,这时候就要有对象去世,这时就会触发一次垃圾回收MinorGC,(就像你出生之后快活了好久要来一次高考),MinorGC触发后,伊甸园区就会对各个对象进行可达性分析,从而知道哪些对象应该作为垃圾被清理。此时采用的算法是标记复制算法,被认为有用的对象复制了出来送到了幸存区,伊甸园展开大杀戮,所有还在伊甸园的对象,都得死。
- 进入幸存区的“考ba”们,将会标记上一个“幸运值”,代表他们抗住了多少次清理。
- 最后,幸存区to和幸存区from还需要交互一下位置,这里不是指物理位置交换,而是说,它俩的定义发生了交换,下次就是左边那个为幸存区to,右边的为幸存区from了。
换句话说,幸存区to始终是空的。幸存区from的人抵挡过一次清理,却要和第二批伊甸园的孩子一起继续接受下一波MinorGC算法的检测和清理。是不是感觉他们好惨??
我们再模拟多几次,加深一下印象,一开始出生并生活在伊甸园,然后一次标记复制算法MinorGC把一些人筛选到了幸存区,伊甸园的人全部死,然后幸存区的to和from交换,此时需要注意,幸存区from中的成员和下一波伊甸园中新成长起来的成员此时就是身份相同的,要一起再次经受MinorGC,不能进入幸存区to照样又得死,空闲的幸存区to则接收下一次从伊甸园和from区逃难来的“考霸”们。考过一次,经历过一次还活着的对象,幸运值+1。
- 当然,你此时对幸运值的价值感到了困惑,幸运值有什么用呢?我们说幸运值是幸存者的寿命,当他们达到一定的数值,就可以进入老年代去养老了,这说明这部分对象是真的很重要。
- 终有一天,养老代也会被占满,此时就会触发第二种Full GC,此时发生大地震,无论新生代还是老年代都会被完全的清理一次。当然Full GC一般就会采用比较简单粗暴地标记整理算法或者标记清除算法了。
还记得这两种算法么?“碎片”和“向一边易位”。
写在最后:
应用上述算法/工作原理/机制的工具叫:垃圾回收器。比较著名的垃圾回收器有: Serial, Parallel Scavenge, CMS, G1等等。
耗了半个多小时,谢谢你们和我一起回顾这段坡脚却又基础的以后又不一定怎么用的到的没用的(关于)垃圾的知识。