jvm垃圾回收机制

11 篇文章 0 订阅

对象已死?

给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就+1,;当引用失效时,计数器值就-1;任何时刻计数器为0的对象就是不可能在被使用。

可达性路径分析法 GC Roots

通过一系列的GC Roots的对象作为起始点,从这些根节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

可以作为GC Roots的对象包括以下几点

虚拟机栈(栈帧中的本地变量表)中引用的对象。

方法区中的类静态属性引用的对象或者常量引用的对象。

本地方法栈中JNI(就是native方法)引用的对象。

分代收集

堆内存结构

一个Jvm实例只有一个堆内存,堆内存的大小是可以调节的,类加载器读取了类文件后,需要把类,方法,常变量放到堆内存中,保存所有引用类型的真实信息,为了方便执行器执行,堆内存分为:

new (新生区) 1 伊甸园区(new 对象 是new在这个区 Eden) 2 幸存者0区(Survivor From) 3 幸存者1区(Survivor To)

old 养老区

永久代(永久存储区 java8以后变成了元空间

堆内存垃圾回收过程

当我们在伊甸园区不断的new对象 超过限度 就会触发GC垃圾回收

伊甸园区 Eden Y = YGC = 轻量级的GC

伊甸园区清空(清空的无引用的) 幸存者(有引用指向)会向下移动到 S0 幸存者0区 幸存对象年龄+1 复制到SurvivorFrom

第二次 一起工作的就是伊甸园区和幸存者0区的一起

又开始不停的new对象 超出限度 触发GC垃圾回收

幸存的对象 向下移动到 S1 幸存者1区 复制到SurvivorTo

当SurvivorFrom区为空时,他和SurvivorTo发生交换**

SurvivorFrom和SurvivorTo区会不断的复制交换 谁空谁就是To区

然后再次GC 当交换的次数到达15次时 如果还有对象存活 就把他放到老年代中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3q7WHn4i-1601964778660)(D:\笔记\weixinobU7Vjgy74mlxHXtfNjiASkZfRtQ\f8aff2bb13ea48a599e38a4dbd217b71\clipboard.png)]

Old养老区 满了 就开启 Full GC = FGC

Full GC多次 发现养老区空间没办法腾出来 就会报OOM 堆内存异常

永久代

常驻内存区域,用于携带JDK自带的Class Interface的元数据,也就是说它存储的时运行环境所必须的类信息,被装载到此区域的数据时不会被垃圾回收器给回收的,关闭jvm也不会释放这个区域的内存。

方法区

习惯把方法区成为永久代 其实是使用永久代来实现方法区 永久代是一个方法的实现。

方法区和堆一样是各个线程共享的内存区域,用于存储虚拟机加载的:类信息 静态常量 普通常量 编译器编译后的代码等等。

方法区并不属于堆内存 它还有个别称叫做 非堆

堆参数调节

堆内存逻辑上分为 新生区 老年区 永久代(8以后换成了元空间)

物理上实际只有新生区 和 老年区 默认空间大小为 1 : 2

Java8以后永久代已经被移除 被一个叫元空间的区域所取代

元空间的本质和永久代类似

永久代使用的是jvm的堆内存

元空间并不在虚拟机中而是使用本机的物理内存。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jaBpgNGl-1601964778663)(D:\笔记\weixinobU7Vjgy74mlxHXtfNjiASkZfRtQ\16786eb40f634644a1b6a8c75a037ea9\clipboard.png)]

-Xms 设置初始分配大小 默认为物理内存的 64分之一

-Xmx 最大分配内存 默认为物理内存的 四分之一

-XX:+PrintGCDetails 输出详细的GC处理日志

GC是什么?

分带收集算法 (次数频繁收集Young区 次数较少收集old区 基本不动元空间)

GC并非是对上面三个内存区域一起回收,大部分时候指的是新生代。

因此GC回收的区域又分成了两种类型,一种是普通GC(Minior GC) 一种是全局GC(Full GC)

普通GC(minor GC)和全局GC(full GC)的区别

普通GC(minor GC)只针对新生代区域的GC 指发生在新生代的垃圾收集动作,因为大多数Java对象存活率不高,所以Minor GC非常频繁。

全局GC(major GC or full GC) 指发生在老年代的垃圾收集动作,出现了Minor GC,经常会伴随至少一次的Minor GC(并非绝对) Full GC速度一般比Minor GC的速度慢10倍以上。 (是因为full GC扫描的范围比较大)

垃圾回收算法

标记清除

老年代一般使用的是标记清楚和标记整理的混合实现

程序运行期间,当可以使用的堆存耗尽的时候,GC线程就会被触发并将程序暂停,然后把需要回收的对象标记一遍,最终统一回收这些对象,完成标记清理工作后接下来让程序恢复运行。

优点 不需要额外的空间

缺点 两次扫描 耗时严重 会产生内存碎片

标记复制

年轻代使用的是Minor GC普通GC回收 使用的就是复制算法

优点是不会产生内存碎片 缺点就是耗费空间

标记整理(标记压缩)

让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存

优点 没有内存碎片 时间短

缺点 需要移动对象的成本

垃圾收集器分类

串行 Serial

为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。所以不适合服务器环境。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pepkdC69-1601964778671)(C:\Users\yan\AppData\Roaming\Typora\typora-user-images\1601795034820.png)]

并行 Parallel

同样会暂停用户进行,不过是多个垃圾回收线程同时运行回收。

多个垃圾回收器同时进行回收 垃圾回收的时间较短 性能比串行好

并发 CMS

用户线程和垃圾收集线程同时执行(不一定是并行 可能是交替执行) 不需要停止用户线程

一边清除垃圾 程序一边跑

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-flwTEGaC-1601964778673)(C:\Users\yan\AppData\Roaming\Typora\typora-user-images\1601795064049.png)]

G1

将堆内存分成不同的区域,分别进行回收

怎么查看服务器默认的垃圾回收器

java -XX:+PrintCommandLineFlags -version

七大垃圾回收器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ehqrtMvi-1601964778674)(C:\Users\yan\AppData\Roaming\Typora\typora-user-images\1601710793751.png)]

SerialGC(Serial(谁瑞哦) Copying)

串行GC 年轻代

只使用一个垃圾回收线程 回收过程中工作线程需要暂停

但是 简单高效 在没有线程交互的开销的情景下可以获得最高的单线程垃圾手机效率。Serial垃圾收集器是java虚拟机在client模式下默认的新生代垃圾回收器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sdW7ZqBD-1601964778675)(C:\Users\yan\AppData\Roaming\Typora\typora-user-images\1601714037352.png)]

ParNewGC

年轻代的并行垃圾回收 年轻代

相对于上面的serial垃圾收集 它是多个垃圾回收线程进行回收 工作线程样也会暂停。效率比serial收集器要快。是很多java虚拟机运行在server模式下的新生代的默认垃圾收集器。

但是老年代还是使用的串行垃圾回收

ParallelGC(Parllallel(怕若累哦) Scavenge(s该文字))

并行GC(java8的默认垃圾回收) 年轻代

并行的多线程的垃圾回收回收器 使用复制算法 也叫吞吐量优先收集器

串行收集器在新生代和老年代的并行化

常用JVM参数:-XX:+UseParaIIeIGC或-XX:+UseParaIIeIOldGC(可互相激活)使用ParallelScanvenge收集器开启该参数后:新生代使用复制算法,老年代使用标记·整理算法

SerialOldGC

已经被淘汰了 老年代

它是Serial收集器的老年代版本,单线程,使用“标记-整理”算法。主要意义是被Client模式下的虚拟机使用。

PallelOldGC

老年代的并行垃圾回收 老年代

它是Parallel Scavenge收集器的老年代版本,****多线程****,使用“标记-整理”算法。

在注重吞吐量及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge+Parallel Old收集器。

ConcMarkSweepHGC (CMS)

并发标记清除GC 老年代

它是一种***以获取最短回收停顿时间为目标***的收集器。

目前很大一部分Java应用都集中在互联网站或B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验,CMS收集器就非常符合这类应用的需求。

  • 初始标记(CMS initial mark):需要“Stop The World”,标记GC Roots能直接关联到的对象,速度快。
  • 并发标记(CMS concurrent mark):进行GC Roots Tracing 过程
  • 重新标记(CMS remark):需要“Stop The World”,修正并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录。停顿时间:初始标记<重新标记<<并发标记
  • 并发清除(CMS concurrent sweep):时间较长

优点 并发收集,低停顿。基于“标记-清除”算法。

缺点 对CPU资源非常敏感 无法处理浮动垃圾 会产生内存碎片

G1GC

G1垃圾回收

  • 基于“标记-整理”算法实现收集器
  • 非常精确地控制停顿

G1收集器可以在几乎不牺牲吞吐量的前提下完成低停顿的内存回收,这是由于它能够极力避免全区域的垃圾收集,之前的收集器进行收集的范围都是整个新生代或老年代,而G1将整个Java堆(包括新生代、老年代)划分为多个大小固定的独立区域(Region),并且跟踪这些区域里面的垃圾堆积程度,在后台维护一个优先列表,每次根据允许的收集时间,优先回收垃圾最多的区域(这就是Garbage First名称的由来)。区域划分、有优先级的区域回收,保证了G1收集器在有限的时间内可以获得最高的收集效率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值