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

JVM知识总结(垃圾收集算法)

文章收录在网站:http://hardyfish.top/

文章收录在网站:http://hardyfish.top/

文章收录在网站:http://hardyfish.top/

文章收录在网站:http://hardyfish.top/

在这里插入图片描述

垃圾收集算法

分代收集理论

分代思想就是将分为新生代老年代,然后根据各个年代的特点选择合适的垃圾收集算法

  • 新生代中,每次收集都会有大量的对象(近99%)死去,所以选择复制算法,只需要付出少量对象的复制成本就可以完成每次收集。

  • 老年代中,对象的存活几率较高,复制成本太高,而且没有额外的空间给它分配担保,所以必须使用标记整理算法或标记清除算法进行垃圾收集。

标记-清除算法

标记-清除算法共有两个阶段,分为标记清除

  • 标记存活的对象,也可以反过来,标记所有需要回收的对象。
  • 在标记完成后统一回收未被标记的对象。

两个明显的问题:

  • 效率问题:如果标记的对象太多,那么效率不高。
  • 空间问题:标记清除后,会产生大量不连续的碎片,空间碎片太多可能会导致当以后在程序运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

复制算法

它可以将内存分为大小相同的两块,每次使用其中的一块,当这一块内存使用完后,就会将存活的对象复制到另外一块去,然后把使用过的空间一次性清理掉,这样就使每次的内存回收都是对内存区间的一半进行回收。

把新生代分为一块较大的Eden空间和两块较小的Survivor空间,每次分配内存只使用Eden和其中一块Survivor。

  • 发生垃圾收集时,将Eden和Survivor中仍然存活的对象一次性复制到另外一块Survivor空间上。
  • 然后直接清理掉Eden和已用过的那块Survivor空间。

HotSpot虚拟机默认Eden和Survivor的大小比例是8∶1:

  • 即每次新生代中可用内存空间为整个新生代容量的90%(Eden的80%加上一个Survivor的10%),只有一个Survivor空间,即10%的新生代是会被浪费的。

复制算法的局限性:

  • 最大的弊端就是浪费内存空间

标记-整理算法

其中的标记过程仍然与标记-清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存。

标记-整理算法的缺点:

要移动存活对象,尤其是在老年代这种每次回收都有大量对象存活区域,而且这种对象移动操作必须全程暂停用户应用程序才能进行。

  • 不移动对象停顿时间会更短,如果从整个程序的吞吐量来看,移动对象会更划算。

HotSpot虚拟机里关注吞吐量的Parallel Scavenge收集器是基于标记-整理算法的。

而关注延迟的CMS收集器则是基于标记-清除算法的。

折中方案:

让JVM平时多数时间都采用标记-清除算法,暂时容忍内存碎片的存在,直到内存空间的碎片化程度已经大到影响对象分配时,再采用标记-整理算法收集一次,以获得规整的内存空间。

  • 基于标记-清除算法的CMS收集器面临空间碎片过多时采用的就是这种处理办法。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 淘客返利系统中的负载均衡与流量控制策略
  • Windows安装MySQL8.0.X版本归档包(zip包)最新教程
  • 【性能优化】Webpack打包优化
  • Android Gradle开发与应用 (一) : Gradle基础
  • 不同专业方向如何在ChatGPT的帮助下完成选题
  • 【JavaEE初阶】懒汉模式与饿汉模式及指令重排序问题
  • Windows图形界面(GUI)-MFC-C/C++ - 列表框(ListBox) - CListBox
  • 分享一个基于微信小程序的旅游自助拼团系统(源码、调试、LW、开题、PPT)
  • C#MQTT协议应用
  • 解决idea debug/run 启动项目一闪而过的问题
  • Docker 设置代理
  • vscode+linux+opencv环境配置
  • 使用ollama取代openai的api进行graphRAG失败记录
  • 《Milvus Cloud向量数据库指南》—Milvus Cloud赋能Ivy.ai:解锁大数据潜力,加速AI创新
  • 低代码: 系统开发准备之确定一般开发流程,需求分析,复杂度分析,标准开发流程
  • [译] 怎样写一个基础的编译器
  • CSS相对定位
  • GraphQL学习过程应该是这样的
  • iOS 系统授权开发
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • Map集合、散列表、红黑树介绍
  • Node项目之评分系统(二)- 数据库设计
  • PHP变量
  • Ruby 2.x 源代码分析:扩展 概述
  • STAR法则
  • Vue ES6 Jade Scss Webpack Gulp
  • 程序员最讨厌的9句话,你可有补充?
  • 浮现式设计
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 老板让我十分钟上手nx-admin
  • 前端性能优化--懒加载和预加载
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 算法-插入排序
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 优秀架构师必须掌握的架构思维
  • ionic异常记录
  • MyCAT水平分库
  • mysql面试题分组并合并列
  • ​字​节​一​面​
  • # Apache SeaTunnel 究竟是什么?
  • $().each和$.each的区别
  • (31)对象的克隆
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (java)关于Thread的挂起和恢复
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (PADS学习)第二章:原理图绘制 第一部分
  • (分布式缓存)Redis分片集群
  • (十) 初识 Docker file
  • (四)Linux Shell编程——输入输出重定向
  • (杂交版)植物大战僵尸
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转)甲方乙方——赵民谈找工作
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程