JVM简单了解

JAVA学习文档

垃圾回收机制

垃圾回收机制是干什么的?

  • 在程序执行过程过程中,会出现有些对象空间被申请但是没有办法直接或者间接被GC Roots对象引用的情况,
    我们称这类空间叫做垃圾空间,需要被清理掉,垃圾回收机制会通过如标记–清除算法(Mark-Sweep)、
    标记–整理算法、复制算法等各类算法实现垃圾空间的清理。但是程序员没法直接清理某项数据,只能通过算法自动化清理。
可以作为GC Roots对象引用的情况
1、虚拟机栈(栈帧中的本地变量表)中引用的对象;
2、方法区中类静态属于引用的对象;
3、方法区中常量引用的对象;
4、本地方法栈中JNI(即一般说的Native方法)引用的对象。

垃圾回收机制是怎么实现的?

内存分类:
垃圾回收机制将Java中存放数据的堆分为了两个部分:
  • 新生代(new):约占堆空间的1/3,存放一些容易被清理的数据
  • 老年代(old):空间占比大约为1/2,存放一些不太容易被清理的数据
新生代和老年代划分依据
  • 数据会首先分配到Eden区当中(当然也有特殊情况,如果是大对象那么会直接放入到
    老年代(大对象是指需要大量连续内存空间的java对象)。当Eden没有足够空间的时候
    就会触发jvm发起一次Minor GC,。如果对象经过一次Minor-GC还存活,并且又能被
    Survivor空间接受,那么将被移动到Survivor空间当中。并将其年龄设为1,
    对象在Survivor每熬过一次Minor GC,年龄就加1,当年龄达到一定的程度(默认为15)时,
    就会被晋升到老年代中了,当然晋升老年代的年龄是可以设置的。
垃圾清理器Minor GC、Major GC、Full GC区别及触发条件:

Minor GC是新生代GC,指的是发生在新生代的垃圾收集动作。由于java对象大都是朝生夕死的,所以Minor GC非常频繁,一般回收速度也比较快。
触发条件:
1.eden区满时,触发MinorGC。即申请一个对象时,发现eden区不够用,则触发一次MinorGC。
2.新创建的对象大小 > Eden所剩空间

Major GC是老年代GC,指的是发生在老年代的GC,通常执行Major GC会连着Minor GC一起执行。Major GC的速度要比Minor GC慢的多。
触发条件:
1.每次晋升到老年代的对象平均大小>老年代剩余空间
2.MinorGC后存活的对象超过了老年代剩余空间
3.永久代(存放的是虚拟机中的方法区)空间不足
4.执行System.gc()
5.CMS GC异常
6.堆内存分配很大的对象
(注:元空间是metaspace,在jdk1.8的时候,jvm移除了永久代的概念,元空间也是对java虚拟机
的方法区的一种实现。元空间与永久代最大的区别在于,元空间不在虚拟机中,使用本地内存。)

Full GC是清理整个堆空间,包括年轻代和老年代
触发条件:基本同Major GC

新生代:
  • 总体约占堆空间的1/3,其中存放的数据容易被清理掉,内部分为三个部分EdDen、From Survivor、To Survivor,占比为8:1:1,
  • 垃圾清理器:Minor GC、Full GC
  • 垃圾收集器:erial、ParNew、Parallel Scavenge、G1
  • 一般适用垃圾回收算法:复制算法
老年代
  • 总体约占堆空间的2/3,其中存放的数据不太容易被清理掉
  • 垃圾清理器:Major GC、Full GC
  • 垃圾收集器:CMS、Serial Old、Parallel Old、G1
  • 一般适用垃圾回收算法:复制算法
垃圾收集器搭配
Serial / Serial Old
Serial / CMS
ParNew / Serial Old
ParNew / CMS
Parallel Scavenge / Serial Old
Parallel Scavenge / Parallel Old
G1


判断对象是否为垃圾(存活)

计数器法:
  • 每个对象在创建的时候,就给这个对象绑定一个计数器。每当有一个引用指向该对象时,计数器加一;每当有一个指向它的引用被删除时,
    计数器减一。这样,当没有引用指向该对象时,计数器为0就代表该对象死亡
  • 优点:实现简单,判定效率也很高
  • 缺点:无法判断互相引用的情况(即无法判断不包含GC Roots的环),如下
    Test a = new Test();
	Test b = new Test();
	/**
	 * 循环引用,此时引用计数器法失效
	 */
	a.object = b;
	b.object = a;
	a = null;
	b = null;
可达性分析法:
  • 从GC Roots开始向下搜索,搜索所走过的路径为引用链。
    当一个对象到GC Roots没用任何引用链时,则证明此对象是不可用的,表示可以回收。
    • 优点:解决相互循环引用问题。
    • 缺点:与计数器法相比无明显缺点

垃圾清理算法:

标记–清除算法(Mark-Sweep)
  • 为每个对象存储一个标记位,记录对象的状态(活着或是死亡)。
    分为两个阶段,一个是标记阶段,这个阶段内,为每个对象更新标记位,检查对象是否死亡;
    第二个阶段是清除阶段,该阶段对死亡的对象进行清除,执行 GC 操作。
  • 标记清除算法的优点:

    1.是可以解决循环引用的问题

    2.必要时才回收(内存不足时)
  • 标记清除算法的缺点:

    1.回收时,应用需要挂起,也就是stop the world。

    2.标记和清除的效率不高,尤其是要扫描的对象比较多的时候

    3.会造成内存碎片(会导致明明有内存空间,但是由于不连续,申请稍微大一些的对象无法做到),
  • 标记清除算法的应用场景:该算法一般应用于老年代,因为老年代的对象生命周期比较长
标记–整理算法
  • 标记清除算法和标记压缩算法非常相同,但是标记压缩算法在标记清除算法之上
    解决内存碎片化(有些人叫"标记整理算法"为"标记压缩算法")标记-整理法是标记-清除法
    的一个改进版。同样,在标记阶段,该算法也将所有对象标记为存活和死亡两种状态;
    不同的是,在第二个阶段,该算法并没有直接对死亡的对象进行清理,
    而是将所有存活的对象整理一下,放到另一处空间,然后把剩下的所有对象全部清除。
    这样就达到了标记-整理的目的。
  • 标记–整理算法优点:解决标记清除算法出现的内存碎片问题,
  • 标记–整理算法缺点:压缩阶段,由于移动了可用对象,需要去更新引用。
  • 标记–整理算法应用场景:该算法一般应用于老年代,因为老年代的对象生命周期比较长。
复制算法
  • 该算法将内存平均分成两部分,然后每次只使用其中的一部分,
    当这部分内存满的时候,将内存中所有存活的对象复制到另一个内存中,
    然后将之前的内存清空,只使用这部分内存,循环下去。
    这个算法与标记-整理算法的区别在于,该算法不是在同一个区域复制,
    而是将所有存活的对象复制到另一个区域内。

  • 复制算法的优点:在存活对象不多的情况下,性能高,能解决内存碎片和java垃圾回收算
    法之-标记清除 中导致的引用更新问题。

  • 复制算法的缺点:会造成一部分的内存浪费。不过可以根据实际情况,将内存块大小比例适当调整;如果存活对象的数量比较大,复制算法的性能会变得很差。

  • 复制算法的应用场景:

    1.复制算法一般是使用在新生代中,因为新生代中的对象一般都是朝生夕死的,存活对象的数量并不多,
    这样使用复制算法进行拷贝时效率比较高。

    2.jvm将Heap(堆)内存划分为新生代与老年代。又将新生代划分为Eden与2块Survivor Space(幸存者区) ,
    然后在Eden –>Survivor Space 与To Survivor之间实行复制算法。

    3.不过jvm在应用复制算法时,并不是把内存按照1:1来划分的,这样太浪费内存空间了。一般的jvm都是8:1。
    也即是说,Eden区:From区:To区域的比例是始终有90%的空间是可以用来创建对象的,
    而剩下的10%用来存放回收后存活的对象。

计数器法(仅了解)
  • 每个对象在创建的时候,就给这个对象绑定一个计数器。每当有一个引用指向该对象时,计数器加一;每当有一个指向它的引用被删除时,
    计数器减一。这样,当没有引用指向该对象时,计数器为0就代表该对象死亡。
  • 优缺点同上。

垃圾收集器

垃圾回收器工作区域回收算法工作线程用户线程并行描述
Serial新生带复制算法单线程Client模式下默认新生代收集器。简单高效
ParNew新生带复制算法多线程Serial的多线程版本,Server模式下首选, 可搭配CMS的新生代收集器
Parallel Scavenge新生带复制算法多线程目标是达到可控制的吞吐量
Serial Old老年带标记-整理单线程Serial老年代版本,给Client模式下的虚拟机使用
Parallel Old老年带标记-整理多线程Parallel Scavenge老年代版本,吞吐量优先
CMS老年带标记-清楚多线程追求最短回收停顿时间
G1新生带 + 老年带标记-整理 + 复制算法多线程JDK1.9以上默认垃圾收集器
G1
  • G1 收集器:分代收集器。当今收集器技术发展最前沿成果之一,是一款面向服务端应用的垃圾收集器。G1可以说是CMS的终极改进版,解决了CMS内存碎片、更多的内存空间登问题。虽然流程与CMS比较相似,但底层的原理已是完全不同。
  • 特点:

    1.能充分利用多CPU、多核环境下的硬件优势;

    2.可以并行来缩短(Stop The World)停顿时间;

    3.也可以并发让垃圾收集与用户程序同时进行;

    4.分代收集,收集范围包括新生代和老年代

    5.能独立管理整个GC堆(新生代和老年代),而不需要与其他收集器搭配;

    6.能够采用不同方式处理不同时期的对象;

    7.应用场景可以面向服务端应用,针对具有大内存、多处理器的机器;

    8.采用标记-整理 + 复制算法来回收垃圾
//使用方法:
设置垃圾收集器:"-XX:+UseG1GC":指定使用G1收集器;
设置垃圾收集器参数:"-XX:InitiatingHeapOccupancyPercent":当整个Java堆的占用率达到参数值时,开始并发标记阶段;默认为45;
设置垃圾收集器参数:"-XX:MaxGCPauseMillis":为G1设置暂停时间目标,默认值为200毫秒;
设置垃圾收集器参数:"-XX:G1HeapRegionSize":设置每个Region大小,范围1MB到32MB;目标是在最小Java堆时可以拥有约2048个Region
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值