深入理解Java虚拟机(四)Eden、Survivor、老年代、GC日志

2023-10-27

1. 年轻代

1.1 Eden区和Survivor区

新生代GC(Minor GC):指发生在新生代的垃圾收集动作,Minor GC非常频繁,新生代采用复制算法,一般回收速度也比较快。因为采用复制算法,所以年轻代分为三部分:1个Eden区和2个Survivor区(分别叫From和To),默认比例为8:1。GC的流程如下:

  • 在GC开始时,对象只存在于Eden区和From区,To是空的。
  • 紧接着,Eden区中所有存活的对象都会被复制到To,而在From区中,仍存活的对象会根据他们的年龄值来决定去向。
  • 年龄达到一定值(年龄值可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中。
  • 没有达到阈值的对象会被复制到To区。
  • 这次GC后,Eden区和From区已经被清空。
  • 此时From和To会交换他们的角色。也就是新的To就是上次GC前的From,新的From就是上次GC前的To。不管怎样,都会保证名为To的Survivor区域是空的。
  • Minor GC会一直重复这样的过程,直到To区被填满,To区被填满之后,会将所有对象移动到年老代中。

如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。

1.2 有关年轻代的JVM参数

  • -XX:NewSize-XX:MaxNewSize:用于设置年轻代的大小,建议设为整个堆大小的1/3或者1/4,两个值设为一样大。

  • -XX:SurvivorRatio:用于设置Eden和其中一个Survivor的比值。

  • -XX:+PrintTenuringDistribution:这个参数用于显示每次Minor GC时Survivor区中各个年龄段的对象的大小。

  • -XX:InitialTenuringThreshol-XX:MaxTenuringThreshold:用于设置晋升到老年代的对象年龄的最小值和最大值。

2. 年老代。

老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。

大对象直接进入老年代。所谓的大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组(byte[]数组就是典型的大对象)。大对象对虚拟机的内存分配来说就是一个坏消息(替Java虚拟机抱怨一句,比遇到一个大对象更加坏的消息就是遇到一群“朝生夕灭”的“短命大对象”,写程序的时候应当避免),经常出现大对象容易导致内存还有不少空间时就提前触发垃圾收集以获取足够的连续空间来“安置”它们。

长期存活的对象将进入老年代。虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1。对象在Survivor区中每“熬过”一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁),就将会被晋升到老年代中。

2.1 年老代涉及的参数

  • -XX:PretenureSizeThreshold令大于这个设置值的对象直接在老年代分配。这样做的目的是避免在Eden区及两个Survivor区之间发生大量的内存复制(新生代采用复制算法收集内存)。

2.2 空间分配担保

在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次Minor GC,尽管这次Minor GC是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次Full GC。

下面解释一下“冒险”是冒了什么风险,前面提到过,新生代使用复制收集算法,但为了内存利用率,只使用其中一个Survivor空间来作为轮换备份,因此当出现大量对象在MinorGC后仍然存活的情况(最极端的情况就是内存回收后新生代中所有对象都存活),就需要老年代进行分配担保,把Survivor无法容纳的对象直接进入老年代。与生活中的贷款担保类似,老年代要进行这样的担保,前提是老年代本身还有容纳这些对象的剩余空间,一共有多少对象会活下来在实际完成内存回收之前是无法明确知道的,所以只好取之前每一次回收晋升到老年代对象容量的平均大小值作为经验值,与老年代的剩余空间进行比较,决定是否进行Full GC来让老年代腾出更多空间。

取平均值进行比较其实仍然是一种动态概率的手段,也就是说,如果某次Minor GC存活后的对象突增,远远高于平均值的话,依然会导致担保失败(Handle Promotion Failure)。如果出现了HandlePromotionFailure失败,那就只好在失败后重新发起一次Full GC。虽然担保失败时绕的圈子是最大的,但大部分情况下都还是会将HandlePromotionFailure开关打开,避免Full GC过于频繁。

3. 日志示例:

虚拟机提供了-XX:+PrintGCDetails这个收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前的内存各区域分配情况。

33.125:[GC[DefNew:3324K->152K(3712K),0.0025925 secs]3324K->152K(11904K),0.0031680 secs]

100.667[FullGC[Tenured:0K->210K(10240K),0.0149142 secs]4603K->210K(19456K),[Perm:2999K->2999K(21248K)],0.0150007 secs][Times:user=0.01 sys=0.00,real=0.02 secs]
  • 最前面的数字33.125:100.667:代表了GC发生的时间。
  • GC日志开头的[GC[Full GC说明了这次垃圾收集的停顿类型,而不是用来区分新生代GC还是老年代GC的。
  • 如果有Full,说明这次GC是发生了Stop-The-World的。
  • 方括号内部的3324K->152K(3712K)表示GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)
  • 方括号外部的3324K->152K(11904K)表示GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)
  • 0.0025925 secs表示该内存区域GC所占用的时间,单位是秒。
  • [Times:user=0.01 sys=0.00,real=0.02 secs],这里面的user、sys和real与Linux的time命令所输出的时间含义一致,分别代表用户态消耗的CPU时间、内核态消耗的CPU事件和操作从开始到结束所经过的墙钟时间(Wall Clock Time)。
  • CPU时间与墙钟时间的区别是,墙钟时间包括各种非运算的等待耗时,例如等待磁盘I/O、等待线程阻塞,而CPU时间不包括这些耗时,但当系统有多CPU或者多核的话,多线程操作会叠加这些CPU时间,所以读者看到user或sys时间超过real时间是完全正常的。

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解Java虚拟机(四)Eden、Survivor、老年代、GC日志 的相关文章

  • 五、Jvm调优

    Jvm调优调什么 这个疑问必须要有 当对一个技术或者系统调优的时候 我们一定要知道去调什么 这样有一个出发点 有一个目标 不能胡乱的调对吧 那么Jvm调优 主要调以下 1 减少Full GC 2 解决OOM 3 总的来说就是 使用较小的内存
  • 图解使用两块 Survivor 区的原因

    如果只使用一块 Survivor 区 当发生一次 Minor GC 时 回收 Eden 区的垃圾 把存活的对象复制到 Survivor 区 如下图 ok 目前看起来并没有什么区别 但是当发生第二次 Minor GC 时 问题就出现了 我们来
  • 数据结构与算法 ---- 线性表 及Java实现 顺序表、链表、栈、队列

    数据结构与算法是程序设计的两大基础 大型的IT企业面试时也会出数据结构和算法的题目 它可以说明你是否有良好的逻辑思维 如果你具备良好的逻辑思维 即使技术存在某些缺陷 面试公司也会认为你很有培养价值 至少在一段时间之后 技术可以很快得到提高
  • 深入理解Java虚拟机(四)Eden、Survivor、老年代、GC日志

    1 年轻代 1 1 Eden区和Survivor区 新生代GC Minor GC 指发生在新生代的垃圾收集动作 Minor GC非常频繁 新生代采用复制算法 一般回收速度也比较快 因为采用复制算法 所以年轻代分为三部分 1个Eden区和2个
  • Java类的加载机制

    一 类的生命周期 1 加载的生命周期 类从被加载到虚拟机内存中开始 到卸载出内存为止 它的整个生命周期包括 加载 Loading 验证 Verification 准备 Preparation 解析 Resolution 初始化 Intial
  • JVM中的新生代和老年代(Eden空间、两个Survior空间)

    现有的主流JVM分别是HotSpot和JRockit 主要研究对象也是这两个 这篇文章里 我们只研究HotSpot 也就是所谓的Sun JVM 目前阶段 Sun的GC方式主要有CMS和G1两种 考虑到效果和实际应用 这里只介绍CMS CMS
  • Java垃圾回收机制

    Java垃圾回收机制 Java垃圾回收机制是指一种自动化的内存管理方式 Java程序员无需手动管理内存 而是由JVM Java虚拟机 自动进行垃圾回收 下面是简要的Java垃圾回收机制 垃圾收集器 JVM中垃圾回收器 Garbage Col
  • 【深入理解Java虚拟机】内存管理和对象访问

    一 JVM内存区域划分 1 程序计数器 线程私有 类似于eclipse中断点程序 行号指示器 记录了程序下一步需要执行的字节码指令 分支 循环等分支 线程私有 每个线程有一个程序计数器 程序计数器是为了多线程情况下 线程执行切换后 处理器回
  • JVM——8.调优工具1(jstat)

    文章目录 1 使用背景 2 jstat 的介绍及使用 2 1 jstat gc PID 介绍 2 2 其他的 jstat命令 2 3 jstat gc PID 使用 3 关注指标及计算分析 3 1 关注指标 3 2 计算分析 1 使用背景
  • java 内存分配策略

    1 对象优先在新生代Eden区中进行分配 当Eden区没有足够空间进行分配时 虚拟机进行一次Minor GC 2 大对象直接进入老年代 所谓大对象就是需要大量连续内存空间的java对象 最典型的大对象就是很长的字符串以及数组 3 长期存活的
  • JVM(java 虚拟机)内存设置

    一 设置JVM内存设置 1 设置JVM内存的参数有四个 Xmx Java Heap最大值 默认值为物理内存的1 4 最佳设值应该视物理内存大小及计算机内其他内存开销而定 Xms Java Heap初始值 Server端JVM最好将 Xms和
  • IO和NIO

    什么是I O模型 通常情况下I O操作是比较耗时的 所以为了高效的使用硬件 应用程序可以专门设置一个线程进行I O操作 而另外一个线程则利用CPU的空闲去做其他计算 这种为提高应用执行效率而采用的I O操作方法称为I O模型 当然了 在网络
  • Java虚拟机——运行时数据区

    Java内存区域 一 介绍 Java内存区域不同于Java内存模型 JMM Java内存区域是指 JVM运行时将数据分区域存储 简单的说就是不同的数据放在不同的地方 通常又叫 运行时数据区域 Java内存模型 JMM 定义了程序中各个变量的
  • little endian && big-endian

    java 的ClassFile采用big endian存储数据 Intel x86 采用little endian Motorola采用big endian 0x1234 Intel 地址 0x4000 0000 0x34 0x4000 0
  • 学习黑马JVM的笔记

    JVM详解 一 JVM介绍 1 什么是JVM 2 有什么好处 3 学习路线 二 内存结构 1 程序计数器 Program Counter Registe 1 定义 2 作用 3 特点 4 演示 2 虚拟机栈 Java Virtual Mac
  • 我看Java虚拟机(2)---Java虚拟机内存区域详解

    虚拟机内存区域的组成 直接上图 程序计数器 对于Java方法 用来选取下一条要执行的字节码 对于本地方法 值为空 线程独有 虚拟机栈 执行Java方法 每一层都是一个栈帧 栈帧包括局部变量表 操作数栈 动态链接和方法出口等信息 线程独有 本
  • 【JVM】如何通俗地讲解JVM各个组成部分和其基本功能?

    类加载器 ClassLoader 运行时数据区 Runtime Data Area 执行引擎 Execution Engine 本地库接口 Native Interface 组件的作用 首先通过类加载器 ClassLoader 会把 Jav
  • 什么是新生代的复制算法

    https blog csdn net ooppookid article details 51523701 1 什么是新生代的复制算法 了解堆内存看这里 java堆内存是什么样的 了解java垃圾回收看这里 java垃圾回收机制是什么 所
  • Java虚拟机二:JVM性能调优

    堆空间的划分 Java中的堆是JVM所管理的最大的一块内存空间 主要用于存放各种类的实列对象 这样划分的目的是为了使JVM能够更好的管理堆内存中的对象 堆的内存划分如图 Java堆的内存划分如图所示 分别为年轻代 Old Memory 老年
  • OpenJDK源码阅读-Oop&Klass

    文章目录 oop klass OBJECT hierarchy metadata hierarchy klass hierarchy oop classDiagram description klass classDiagram descr

随机推荐

  • C语言图书馆管理系统

    C语言图书馆管理系统 全部代码如下 include
  • 异步Windows Socket包装,包括TCP与UDP,可处理粘包

    头文件 struct IPAddress union struct IPV4Address ULONG host USHORT port address UINT64 64 static IPAddress Zero ULONG GetHo
  • SteamVr、VRTK配置

    版本 SteamVr 1 2 3 VRTK 3 3 0 Unity 2019 4 28f1c1 VRTK配置 新建空对象 命名为SDKManager 添加VRTK SDK Manager 脚本 作用 管理各种VRSDk 在SDKManage
  • Android高德地图marker自定义弹框窗口

    最终效果 1 gradle里添加高德地图依赖 implementation com amap api map2d latest integration 2d地图功能 implementation com amap api location
  • 前端基础篇之 CSS 世界

    前端基础篇之 CSS 世界 基本概念 这些基本概念有些可能不易理解但却都很重要 如果看完还是很不理解的话需要自己谷歌或百度 网上关于这些概念的文章不少 流 流 又叫文档流 是 css 的一种基本定位和布局机制 流是 html 的一种抽象概念
  • 【pandas】to_datetime函数简单使用

    该函数将给定参数args转换为日期格式 需要传入参数format指定args的格式 注意format中年用Y表示 月和天用小写的m和d表示 pd to datetime 20220517 format Y m d gt gt gt Time
  • sweetalert2中ajax用法,SweetAlert2 使用教程

    SweetAlert2是一款功能强大的纯Js模态消息对话框插件 SweetAlert2用于替代浏览器默认的弹出对话框 它提供各种参数和方法 支持嵌入图片 背景 HTML标签等 并提供5种内置的情景类 功能非常强大 SweetAlert2是S
  • ChatGPT 全面解析

    ChatGPT问世 12月1日 美国人工智能公司OpenAI在网页上推出自然语言处理领域 NLP 的模型ChatGPT 它能够通过对话方式进行交互 并根据用户输入的自然语言文本内容 自动生成新的文本内容 一周内 ChatGPT的用户已突破1
  • 写每个程序员的第一个代码--Hello World程序

    1 首先创建一个文本文档 并输入以下代码 public class HelloWorld public static void main String args System out println Hello World 2 然后对程序重
  • 五子棋游戏(Java编写)双人对赛

    目录 1 游戏准则 2 游戏细节 代码如下 运行结果 bug测试 棋子重复 棋子越界 1 游戏准则 黑子白子依次下棋 不能重复 也不能越界 若违规 则重新下棋 判断输赢 判断各方向是否五个棋子连在一起 若有则胜 若无 则败 2 游戏细节 白
  • Docker 进行 apt 等操作时无法连接源

    Docker 进行 apt 等操作时无法连接源 重启 Docker 参考文章 sudo service docker restart or sudo etc init d docker restart
  • 【网络安全】一段小笑话学习 加密算法+盐

    催生这篇文章的一个原因是一位讲了半天听不懂原理还不虚心学习的群友 小笑话 群友 为啥两个一样的密码一个可以登录一个不可以 群友 不同用户名 群友 A账号 B密码 C账号 B密码 居然a能登陆c提示密码错误 群友 没有改东西 想必大部分人肯定
  • Python110道常见面试题

    干货 110 道 Python 面试笔试题超强汇总 这几天好多留言问有没有Python面试题 今天统一给大家分享一遍 希望能帮助此时仍在找工作的同学 尽快找到工作 希望对基本知识不熟悉的同学 能认真做一遍 肯定会有不少收获 1 一行代码实现
  • DB2时间戳查看

    1 打开日志 确定错误是那个数据库操作造成 2 查看bnd文件的时间戳信息 db2bfd b Card bnd grep Timestamp 显示时间戳 Timestamp tA5MPfMZ 2009 12 31 15 12 56 45 3
  • linux服务器下手动删除memcache中的key对应的value

    假设服务器ip是 10 0 0 1 端口是 1234 首先连上服务器 telnet 10 0 0 1 1234 查看某个key对应的值 假设key的名称为 type get type 获取值 delete type 删除
  • Anaconda下pip离线安装Pytorch(亲测可用)

    win10 Anaconda3 python3 7 CUDA10 进入pytorch官网https pytorch org 根据自己情况选择安装 注意 我并没有在Anaconda Prompt下直接输入Run this Comman的内容
  • 2023年十大最佳自动化测试工具

    Best Automation Testing Tools for 2023 对更快交付高质量软件 或 快速质量 的需求要求组织以敏捷 持续集成 CI 和DevOps方法论来寻找解决方案 测试自动化是这些方面的重要组成部分 最新的 2018
  • ContentProvider与ContentResolver

    1 理解ContentProvider与ContentResolver 看下面这个图就行了 2 ContentProvider可以直接理解为一个public的servlet类 里面 封装了一些public 的函数 这个函数可以操作数据库 文
  • C++11 并发指南三(Lock 详解)

    C 11 并发指南三 Lock 详解 文章目录 C 11 并发指南三 Lock 详解 std lock guard 介绍 std lock guard 构造函数 std unique lock 介绍 std unique lock 构造函数
  • 深入理解Java虚拟机(四)Eden、Survivor、老年代、GC日志

    1 年轻代 1 1 Eden区和Survivor区 新生代GC Minor GC 指发生在新生代的垃圾收集动作 Minor GC非常频繁 新生代采用复制算法 一般回收速度也比较快 因为采用复制算法 所以年轻代分为三部分 1个Eden区和2个