JVM垃圾回收及相关算法
1.Java 和 C++语言的区别,就在于垃圾收集技术和内存动态分配上,C++语言没有垃圾收集技术,需要程序员手动
的收集。
2.垃圾回收机制:能够提高开发效率
1.什么是垃圾
垃圾是指在运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。
如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空间会一直保留到应用程序结束,被保留的
空间无法被其他对象使用。甚至可能导致内存溢出。
2.垃圾回收机制
自动内存管理
自动内存管理的优点
自动内存管理,无需开发人员手动参与内存的分配与回收,这样降低内存泄漏和内存溢出的风险.
3.垃圾回收相关算法
1.标记阶段的目的
目的:判断对象是否存活,是否能够回收
1.在堆里存放着几乎所有的 Java 对象实例,在 GC 执行垃圾回收之前,首先需要区分出内存中哪些是存活象,
哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC 才会在执行垃圾回收时,释放掉其所占用的内存
空间,因此这个过程我们可以称为垃圾标记阶段。
判断对象存活一般有两种方式:引用计数算法和可达性分析算法。
1.1引用计数算法
1.引用计数算法比较简单,对每个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。
2.优点:实现简单,垃圾对象便于辨识;判定效率高,回收没有延迟性。
3.缺点:
1.它需要单独的字段存储计数器,这样的做法增加了存储空间的开销。
2.每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了时间开销。
3.引用计数器有一个严重的问题,即无法处理循环引用的情况。这是一条致命
缺陷,导致在Java 的垃圾回收器中没有使用这类算法。
1.2可达性分析算法
可达性分析算法:也可以称为根搜索算法、追踪性垃圾收集
特点:该算法可以有效地解决在引用计数算法中循环引用的问题,防止内存泄漏的发生。
1.可达性分析算法是以根对象集合(GCRoots)为起始点,按照从上至下的方式搜索被根对象集合所连接的目标对象是否可达。
2.使用可达性分析算法后,内存中的存活对象都会被根对象集合直接或间接连接着,搜索所走过的路径称为引用
链
3.如果目标对象没有任何引用链相连,则是不可达的,就意味着该对象己经死亡,可以标记为垃圾对象。
4.在可达性分析算法中,只有能够被根对象集合直接或者间接连接的对象才是存活对象
2.垃圾回收阶段算法
当成功区分出内存中存活对象和死亡对象后,GC 接下来的任务就是执行垃圾回收,释放掉无用对象所占用的内存
空间,以便有足够的可用内存空间为新对象分配内存。目前在 JVM 中比较常见的三种垃圾收集算法是:
标记-清除算法(Mark-Sweep)
复制算法(Copying)
标记-压缩算法(Mark-Compact)
2.1标记-清除算法(Mark-Sweep)
执行过程
当堆中的有效内存空间被耗尽的时候,就会停止整个程序(也被称为 stop the world),然后进行两项工作,第一项则是标记,第二项则是清除
标记:使用可达性分析算法
清除:有一个集合,记录垃圾位置, 有新对象时,覆盖垃圾位置
标记-清除算法的优点:非常基础和常见的垃圾收集算法容易理解
缺点:标记清除算法的效率不算高,产生内存碎片
2.2复制算法(Copying)
为了解决标记-清除算法在垃圾收集效率方面的缺陷,它将可用内存按容量划分为大小相等的两块,每次只使用其
中的一块。在垃圾回收时将正在使用的内 存中的存活对象复制到未被使用的内存块中,之后清除正在使用的内存
块中的所有对象,交换两个内存的角色,最后完成垃圾回收。
优点: 对于少量对象操作,运行快,不会产生内存碎片。
缺点:内存需要2块, 对象发生复制,对大量对象操作效率低.
2.3标记-压缩算法(Mark-Compact)
第一阶段和标记清除算法一样,从根节点开始标记所有被引用对象
第二阶段将所有的存活对象压缩到内存的一端,按顺序排放。之后,清理边界外所有的空间。
优点
消除了标记-清除算法当中,内存区域分散的缺点,我们需要给新对象分配内存时,JVM 只需要持有一个内存的起始地址即可。消除了复制算法当中,内存减半的高额代价。
缺点
从效率上来说,标记-整理算法要低于复制算法。移动对象的同时,如果对象被其他对象引用,则还需要调整引用的地址移动过程中,需要全程暂停用户应用程序。
2.4总结
因为不同的情况需要不同的算法所以进行分代
年轻代与老年代
年轻代特点:区域相对老年代较小,对象生命周期短、存活率低,回收频繁。所以使用复制算法速度快
老年代特点:区域较大,对象生命周期长、存活率高,回收不及年轻代频繁。标记压缩和标记清除混合实现
2.5增量算法
上述现有的算法,在垃圾回收过程中,应用软件将处于一种 Stop the World 的状态。在 Stop the World 状态下,
应用程序所有的线程都会挂起,暂停一切正常的工作,等待垃圾回收的完成。如果垃圾回收时间过长,应用程序会
被挂起很久,将严重影响用户体验或者系统的稳定性。为了解决这个问题,即对实时垃圾收集算法的研究直接导致
了增量收集算法的诞生。
每次回收部分垃圾, 回收线程和用户线程交替执行.减少用户线程停顿时间.
World 状态下,应用程序所有的线程都会挂起,暂停一切正常的工作,等待垃圾回收的完成。如果垃圾回收时间过长,应用程序会
被挂起很久,将严重影响用户体验或者系统的稳定性。为了解决这个问题,即对实时垃圾收集算法的研究直接导致
了增量收集算法的诞生。
每次回收部分垃圾, 回收线程和用户线程交替执行.减少用户线程停顿时间.
缺点: 切换次数开销增大, 每次回收垃圾少