java比c++强大之处jvm垃圾收集算法

java可以自动进行垃圾收集,c++需要手动释放内存,这个功能将程序员解放出来,能将更多的注意力放在需要实现的业务上,这也是java相对c++的一个巨大优势,jvm有哪些垃圾收集算法呢?

  1. 标记清除算法:算法分为标记和清除两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象

从图中可以看出这种算法的缺点在于,垃圾被回收以后造成了大量不连续的内存碎片。碎片太多可能会导致以后需要分配较大对象时,无法找到连续的足够内存从而频繁触发垃圾收集,降低系统效率。

  1. 复制算法:为了解决“标记,清除”算法的问题一种被称为复制的算法出现了,它将内存平均分为两块,每次只使用其中一块,当这一块存满时触发垃圾收集,将还存活的对象复制到另一块内存,然后将这块内存清掉,这样就不会存在内存碎片的问题。
  2. 标记整理算法:
    复制算法在存活对象较多的时候需要复制的操作也较多,最关键的是只能利用一半的内存,标记整理算法可以解决这个问题,标记整理算法中的标记和标记清除算法一样,要被回收的对象找出来以后让所有存活的对象向一端移动,然后将内存的剩余部分直接清理掉。
    1
  3. 分代收集算法:
    分代收集算法将内存分为新生代和老年代,新生代又分为:较大的Eden区(占80%)和两块Survivor区(各占10%),刚刚创建的对象存放在新生代的Eden区
    ,因为绝大多数的对象(98%)都是朝生夕死的,当Eden区没有足够的空间的时候虚拟机会发起一次Minor Gc,Minor Gc之后,存活对象会进入其中的一块Suvivor区,Eden区被清空,如果Suvivor区内存不够则直接进入老年代。下一次Minor Gc会将Eden和该Suvivor区的存活对象复制到另一块Suvivor区,并将Eden区和该Suvivor区清空。
    在这里我们可以看到相比复制算法,被浪费的空间只有10%。但是前提是绝大部分(90%)的对象在Mino Gc的时候会被回收,如果不满足这个条件Suvivor区大小不够,则存活的对象直接进入老年代。
    为什么需要Survivor区?
    试想一下如果没有Survior区,每次进行Minor Gc,存活的对象直接进入老年代,老年代内存被占满会发生Major Gc,Major Gc执行的速度比Minor Gc慢十倍以上,当有了Survivor区,存活的对象在两块Survior区中倒腾,当倒腾的次数达到16次说明这个对象生命力真的很顽强,才会被放入老年代。这样就减少了Major Gc发生的频次。

为什么需要两块Survivor区?
为了避免内存碎片化的问题,大家想想复制算法是如何解决标记清除算法的内存碎片化问题的,将内存分为大小相等的两块,将存活的对象复制到另一块内存,这里也是一样的道理。

老年代:
因为老年代中对象的生命力比较顽强,如果采用复制算法那些存活的对象需要被复制很多次,所以老年代采用的是标记整理算法。

什么样的对象会进入老年代呢?

  1. 大对象会直接进入老年代:
    所谓的大对象就是指需要大量连续内存空间的对象,典型的大对象就是很长的字符串和数组,如果大对象直接在Eden区分配内存空间会导致Eden和Survior之间的大量内存复制,很消耗性能,所以它会直接进入老年代。
  2. 长期存活的对象会进入老年代
    所谓长期存活的对象就是前面所述,来回倒腾十六次还不死的对象。

原文地址:https://blog.51cto.com/11583017/2468307

时间: 2024-08-04 20:55:26

java比c++强大之处jvm垃圾收集算法的相关文章

JVM垃圾收集算法(标记-清除、复制、标记-整理)

 [JVM垃圾收集算法] 1)标记-清除算法: 标记阶段:先通过根节点,标记所有从根节点开始的对象,未被标记的为垃圾对象(错了吧?) 清除阶段:清除所有未被标记的对象 2)复制算法: 将原有的内存空间分为两块,每次只使用一块,在垃圾回收时,将正在使用的内存中的存活对象复制到未被使用的内存块中,然后清除正在使用的内存块中的所有对象. 3)标记-整理算法: 标记阶段:先通过根节点,标记所有从根节点开始的可达对象,未被标记的为垃圾对象 整理阶段:将所有的存活对象压缩到内存的一段,之后清理边界所有的空间

jvm 垃圾收集算法

经过上篇如何判断对象是否死亡,那么jvm要对死亡的对象进行垃圾回收,垃圾回收的算法主要有以下几种: 一.标记-清楚算法 该算法分为“标记”和“清除”阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象.它是最基础的收集算法,后续的算法都是对其不足进行改进得到.这种垃圾收集算法会带来两个明显的问题: 一个是效率问题,标记和清除两个过程的效率都不高 一个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的

【004】【JVM——垃圾收集算法】

 垃圾收集算法 垃圾收集算法的实现涉及大量的程序细节,而且各个平台的虚拟机操作内存的方法又各不相同,介绍几种垃圾收集算法的思想及其发展过程. 标记-清除算法 垃圾收集分为"标记"和"清除"两个阶段:首先标记所有需要回收的对象,在标记完成后统一回收所有被标记的对象.说它是最基础的收集算法,其他收集算法都是基于这种思路并对其不足进行改进而得到的.它的主要不足有两个: 效率问题,标记和消除两个过程的效率都不高: 空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎

java垃圾回收Garbage Collection(一、垃圾收集算法)

垃圾收集算法 标记-清除算法 最基础的算法是标记-清除(Mark-Sweep)算法.分为标记和清除两个阶段:首先标记出所有需要回收的对象,标记完成后统一回收所有被标记的对象.之所以说是最基础的收集算法,是因为后续的收集算法都是基于这种思路并对其不足进行改进而得到的.它主要有两个不足之处:一个是效率标记和清除效率都不高:另一个是空间问题标记清除后产生大量的不连续内存碎片,空间碎片过多可能会导致以后程序运行过程中需要分配较大的对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作.标记清除算

JVM垃圾收集算法的选择

1. 介绍 JVM提供了多种垃圾收集器,应该根据应用选择一种合适的垃圾收集器. 垃圾回收管理内存通过如下操作: 在年轻代分配对象,把年龄大的对象晋升到老年代. 当年老代超过阈值的时候,并发标记收集. 通过合并内存,拷贝内存的方式对内存进行整理,回收可以内存. 垃圾回收什么时候会产生问题?对于有些应用,垃圾回收永远都不会成为问题,有些应用在垃圾回收期间短暂的暂 停,适当的垃圾回收频率下也可以表现的很好. 阿姆达尔定律(http://ifeve.com/amdahls-law/)意味着程序的性能受限

JVM——垃圾收集算法

标记-清除算法 复制算法 标记-整理算法 分代收集算法 1.标记-清除算法 最基础的收集算法,如其名,算法为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. 两个不足: 1)效率问题,标记和清除两个过程的效率多不高: 2)空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前出发另一次垃圾收集动作. 2.复制算法 这种算法是为了解决效率的问题.它将可用内存按

Jvm垃圾收集算法

标记-清除 标记-清除算法是现代垃圾回收算法的思想基础.标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段.一种可行的实现是,在标记阶段,首先通过根节点,标记所有从根节点开始的可达对象.因此,未被标记的对象就是未被引用的垃圾对象.然后,在清除阶段,清除所有未被标记的对象 标记-整理 根据老年代的特点提出标记-整理算法.它在标记-清除算法的基础上做了一些优化.和标记-清除算法一样,标记-整理算法也首先需要从根节点开始,对所有可达对象做一次标记.但之后,它并不简单的清理未标记的对象,而是将所有

JAVA程序员养成计划之JVM学习笔记(2)-垃圾收集管理

本文对JVM垃圾收集进行说明,包括三种不同算法(标记复制.标记清除.标记整理),以及七种不同的垃圾收集器(Serial,ParNew,Serial Scavenge, CMS, Serial Old, Parallel Old, G1) 持续更新中- - 1. 垃圾回收相关概念 1.1. 垃圾回收对象 说到垃圾收集,首先得确定哪些是可回收的对象,这里涉及到java的四种引用方式,即强.软.弱.虚四类引用. 强引用:即普遍存在的对对象的引用,如指向通过new创建的对象 软引用:即程序运行非必须的对

【Java 之 JVM】垃圾收集算法

一.判断对象是否存活--可达性分析算法 基本思想:通过一系列成为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots 没有任何引用相连则证明该对象是不可用的.在判断完无链之后,还需经历两次标记过程,才会真正回收,暂略. 二.垃圾收集算法 1.标记--清除算法 标记出所有需要回收的对象,标记完统一回收.缺点:标记,清除2个过程效率都不高,大量不连续的内存碎片. 2.复制算法 将内存划分为大