GC的垃圾回收算法以及一些GC的概念

如果定义"垃圾"?

   没有引用指向的任何对象都叫做"垃圾"
   java是由GC帮助回收垃圾,开发效率高,但是执行效率低。

如何找到"垃圾"?

  1.引用计数:有一个引用指向对象就在这个对象上计数加一,不能解决循环引用问题(会一直引用计数为1,没有其他引用指向他们)。
  2.根可达算法:从根对象开始搜索(根对象:线程栈变量,静态变量,常量池,JNI指针(调用了C,C++本地方法叫JNI指针)(程序起来就要用的对象就是根对象))根据根对象找不到,叫做垃圾

垃圾回收算法

Mark-Sweep 标记清除

  1.通过GC roots 要进行两次扫描(第一遍找出有用的,第二遍把没用的找出来清理,第一次标记第二次清除)
  2.容易产生碎片(回收了之后前面不压缩不整理会产生空缺)
  3.存活对象比较多的时候效率就会很高,从根找出来的存活对象多,要清除的比较少。

Copying 拷贝

  1.内存一分为二,有用的拷贝到一边,另一边没用的全都清除掉
  2.会发生对象的复制和移动,需要调整对象引用(因为对象被移动了)
  3.只需要进行一遍扫描,然后复制对象,适用于存活少,需要回收的多

Mark-Compact 标记压缩

   1.有用的全都整理到前面去,剩下的其他没用的全都清除掉
   2.空间连续没有碎片,找到不可回收的移动到前面扫描两次还要移动对象(第一遍找出有用的,第二遍移动)
   3.不会产生碎片,方便对象分配,内存不会减半

堆内存逻辑分区(不适合不分代的垃圾收集器)

hotSpot用的是分代算法

新生代大量死去,少量存活,采用复制算法
老年代存活率搞,回收较少,采用mc或者ms

堆内存分区示意图
新生代/老年代=1:2(分代模型里面默认的关系)

部分垃圾回收器使用分代模型

    除Epsilon ZGC Shenandoah的GC都是使用逻辑分代模型
    G1是逻辑分代,物理不分代
    除此之外不仅逻辑分代,而且物理分代

一个对象的消亡过程

   1.对象产生的时候会尝试栈上分配
   2.栈上分配不下会尝试放到伊甸区
   3.伊甸区经过一次垃圾回收之后进入s区
   4.s区再经过一次垃圾回收之后进入s1区
   5.然后再s和s1之间来回,什么时候年龄到了就进入old区(多次垃圾回收进入old区)

新生代回收的叫MinorGC/YGC:年轻代空间耗尽时触发
MajorGC/FullGC:老年代无法继续分配空间时触发,新生代老年代同时进行回收

什么对象会分配到栈上?

线程私有小对象:小对象,线程私有。
无逃逸:就在某一段代码使用。
支持标量替换:用普通属性代替对象。

线程本地分配TLAB

 1.在栈上分配不下了就会进行线程本地分配占用eden。默认百分之1 (每个线程占用百分之1,免得线程竞争,这个线程独有,分配对象的时候先往线程独有的地方分配)
 2.多线程的时候不用竞争eden就可以申请空间,提高效率
 3.小对象

老年代

   大对象

在打开栈上分配和线程本地分配产生对象的效率会变高,速度会快。

对象何时进入老年代

超过XX:MaxTenuringThreshold指定次数(YGC)

不指定默认如下:
1.parallel scavenge 15
2.cms 6
3.g1 15

动态年龄

1.s0->s1超过50%:s0对象拷贝到s1里面,且此时S1中对象超过百分之五十的话,就把年龄最大的放进old区
2.把年龄最大的放入Old

ps:1.8的新生代老年代对比,查询命令
java -XX:PrintFlagsFinal -version | grep NewRatio

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值