当前位置: 首页 > news >正文

GC垃圾回收

1:GC

回收区域:堆和方法区(线程共享的区域存在垃圾回收,线程私有的区域不存在垃圾回收)

栈是线程销毁才会回收,栈帧是某次方法调用后返回才销毁(自动回收,无需GC)

Java语言不用程序员自己分配内存,也不需要自己回收内存,原因就是JVM中实现的垃圾回收机制(自动回收)

方法区:保存静态变量和类信息,很少回收,比如老版本的JVM就不会回收方法区,所有会产生内存泄漏

堆:回收的主要区域

发生GC的时间:对象进入老年代或者新生代,如果该区域空间不足则会触发该区域的GC。

新生代GC:minorGC,采取复制算法,效率比较高

老年代GC:majorGC,标记清除算法,标记整理算法,效率比较差

1:死亡对象的判断算法

1:引用计数算法

给对象增加一个引用计数器,当有一个地方引用它,则+1,当引用失效-1,任何时刻当计数器为0则不能在被引用,即对象已死,变成垃圾。

JVM没有采取这种方式,无法计算循环引用问题

2:可达性分析算法

GC Roots:垃圾回收要检查的根节点

引用链:某个对象到GC Roots的路径,对象间的引用关系表现出的连接关系

不可达对象:一个对象到GC Roots是不可达的,就是一个垃圾

2:垃圾回收算法

1:老年代回收算法-----标记清除算法

流程:先将需要回收的对象一个一个进行标记,再对标记的对象一个一个进行删除

效率问题:效率不高,标记和回收时需要进行遍历

空间问题:回收后产生大量不连续的内存空间,内存碎片

2:新生代回收算法-----复制算法

流程:将内存区域划分为两个大小相等的空间,在回收时,将存活的对象复制到另外一块未使用的内存空间中,清除之前使用的空间

使用场景:大多数对象具有朝生夕死的特性(很多方法调用,使用局部变量等于new的对象,方法执行结束这些对象即可回收),新生代对象符合朝生夕死的对象

空间问题:空间利用率只有50%

新生代回收算法的改进:

JVM中新生代的回收算法是基于复制算法的优化版本,因为新生代的对象很多都是朝生夕死的,所以并不需要按照1:1划分内存,而是将新生代分为较大的Eden(伊甸园)和两块较小的Survivor(幸存者)空间,ES比为8:1,空间利用率达到90%。每次只使用伊甸区和其中一块幸存区,称为from区,另一个幸存区称为to区。回收时,将from区存活的对象复制到to区,再清理from区。如果一个对象再两个存活区交换15次,则会放入到老年代。

3:老年代回收算法-----标记-整理算法

流程:标记存活对象,将存活对象往一侧移动,然后清除端边界另外一半的空间

4:分代算法

流程:JVM采取的算法,本质上没有具体算法实现,只是通过区域划分,实现不同区域的不同垃圾回收策略

将内存(堆)划分为新生代,一个E区,两个S区,以及老年代。

针对新生代采取改进的复制算法,老年代使用标记清除或者标记整理算法。

新生代和新生代:

一般创建的对象放入新生代,但是大对象(对象占据的空间超出JVM设置的阈值)创建后进入老年代。新生代中连续交互15次的对象。新生代GC时,分配担保失败的对象(8+1中存活的对象放到另外一个1中,如果放不下则放入老年代)

3:垃圾回收器

新生代收集器:

  • Serial
  • ParNew
  • Parallel Scavenge

老年代收集器:

  • Serial Old
  • Parallel Old
  • CMS

全堆收集器:

  • G1

垃圾回收线程:守护线程,可并行执行,用户线程可以和垃圾回收线程并发执行或者等待(STW,Stop the world)

吞吐量:执行用户代码时间/(执行用户代码时间+垃圾回收时间),表达出一个程序的效率好不好

1:CMS垃圾收集器—老年代

Concurrent Mark Swap:并发标记清除

1:老年代收集器

2:标记清除算法

3:用户体验优先,垃圾回收线程和用户现场同时执行,存在局部的STW(少许时间暂停用户线程)

4:并发收集,低停顿

CMS搭配新生代的ParNew收集器,以此给用户更好的体验

收集过程:

  • 初始标记:标记GC Roots能直接关联的对象(这个阶段需要STW)
  • 并发标记:进行GCRoots引用链追踪的过程,搜索引用路径(这个阶段可以和用户线程并发)
  • 重新标记:修正并发标记阶段,和用户线程并发执行时,修复标记产生变动的记录(这个阶段需要STW)
  • 并发清除:并发清除垃圾,和用户线程并发

缺点:

  • 对CPU资源比较敏感(可能产生CPU不足的问题)
  • 无法处理浮动垃圾(是第四阶段时用户线程并发执行时产生的垃圾)
    • 需要预留空间给浮动垃圾
    • 不知道具体预留空间大小,如果浮动垃圾超出预留空间大小则产生失败 Concurrent Model Failure (并发模式失败)
    • 超出预留空间则会再次触发一次老年代的GC,且是Serial Old单线程的收集器回收
  • 标记清除算法本身的空间碎片问题的产生,且可能导致提前触发GC

2:G1垃圾收集器—全堆的垃圾回收器

使用G1收集器时,堆的内存划分:划分为一个一个的region区,动态分配为E区(伊甸),S区(幸存),T区(老年)

特性:

  • 全堆收集器
  • 整体看基于标记-整理算法,局部看是基于复制算法
  • 用户体验优先的收集器

新生代回收步骤:回收多个E区和S区,复制存活对象到空的region,再重新定义为S区

老年代回收步骤:

  • 初始标记阶段:标记GC Roots能直接关联的对象(这个阶段需要STW),可以和新生代GC同时执行

  • 并发标记:进行GCRoots引用链追踪的过程,搜索引用路径(这个阶段可以和用户线程并发),优先回收(Garbage First)存活率低或者几乎没有存活的region

  • 最终标记阶段:修正并发标记阶段,和用户线程并发执行时,修复标记产生变动的记录(这个阶段需要STW)

  • 筛选回收阶段:筛选存活率低的region,可以和新生代GC同时执行

2:JMM

JMM:Java内存模型,用来屏蔽各种硬件和操作系统的内存访问差异,实现让Java程序在各平台下能达到一致的内存访问效果

中间内存:属于硬件层面的中间内存,而不是JMM的概念

主存:存放线程共享的数据

工作内存:存放线程私有的,以及共享变量的拷贝

8大原子性的字节码指令:用于主存和工作内存的数据读取操作

Java内存模型的三大特性:

  • 原子性:八大字节码层面的原子性指令,基本数据类型的访问具备原子性
  • 可见性:当一个线程修改了共享变量的值,其它线程能够可见
  • 有序性:本线程内观察,所有的操作都是有序的,在另一个线程观察所有操作是无序的

相关文章:

  • 3D场景的制作步骤
  • 【精讲】后台项目 采用vue2框架 完整版内含详细注释 2
  • mac vscode debug安装调试moodle
  • PyTorch(一)安装与环境配置
  • 全网最牛自动化测试框架系列之pytest(7)-yield与终结函数
  • JSR303校验(1)
  • Nacos - 支持PostgreSQL
  • CFD网格质量评估标准
  • 网课答案公众号题库系统
  • 详解AVL树(二叉搜索平衡树)【C++实现】
  • 网课答案公众号搭建方法
  • 牛客网练习题(函数部分)
  • 仿everything的文件搜索工具项目详解:Part3
  • React中this.setState方法原理解析(详解)
  • jquary
  • 【前端学习】-粗谈选择器
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • Angular4 模板式表单用法以及验证
  • Babel配置的不完全指南
  • const let
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • Java,console输出实时的转向GUI textbox
  • js
  • mongodb--安装和初步使用教程
  • nfs客户端进程变D,延伸linux的lock
  • node和express搭建代理服务器(源码)
  • STAR法则
  • Vue.js 移动端适配之 vw 解决方案
  • Vue组件定义
  • 高度不固定时垂直居中
  • 猴子数据域名防封接口降低小说被封的风险
  • 后端_ThinkPHP5
  • 开发基于以太坊智能合约的DApp
  • 如何合理的规划jvm性能调优
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 一道面试题引发的“血案”
  • 用Python写一份独特的元宵节祝福
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #mysql 8.0 踩坑日记
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (13)Hive调优——动态分区导致的小文件问题
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (七)c52学习之旅-中断
  • (推荐)叮当——中文语音对话机器人
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • ***测试-HTTP方法
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .Net Remoting常用部署结构
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调