【高频Java面试题】简单说说JVM堆的内存结构和GC回收流程
前言
我们在Java面试中,只要是2年以上经验,一定会问你一下关于JVM方面的问题。开发两年时间不能对JVM没有了解,如果你还不了解,说明你的学习与探索能力不高,不能给到应有的加分项哦!小编也是最近刚刚开始学习,总结一下最近的学习成果。方便以后看,也希望小伙伴们看到可以帮助到您!
JVM堆内存结构简述
JVM堆内存结构图
堆初体验
所有的对象实例以及数组都要在堆上分配,堆是垃圾收集器管理的主要区域,也被称为“GC 堆
”,也是我们优化最多考虑的地方。因为在一个项目中,会不断地创建对象,都是在堆里创建,如果一直不回收就会导致OOM
,我们听的最多的情况哈!还有经常说的JVM调优
,也是对堆
进行参数优化配置,达到最接近理想状态。
结构详情
新生代
大部分刚创建的对象首先都是放在年轻代,新生代内存按照 8:1:1 的比例分为一个
Eden 和两个 Survivor
(Survivor from,Survivor to)。
1. Eden 空间
Eden空间:主要是存放刚刚创建的新对象,如果可以Eden空间充足,新对象直接存放在Eden中,如果对象过大,放不下则会触发
Minor GC(效率很快)
。
2. Survivor 空间
每次执行Minor GC,会将Eden区中存活的对象放到Survivor的From区,而在From区中,仍存活的对象会根据他们的年龄值来决定去向,逃过一次Minor GC年龄
加1
,默认年数为15
,就要到老年区
。(From Survivor和To Survivor的逻辑关系会在GC时发生颠倒
: From变To , To变From,目的是保证有连续的空间存放对方,避免碎片化的发生,后面GC流程在详细说)
老年代
在新生代中经历了 N 次(
默认15次
)垃圾回收后仍然存活的对象,就会被放到年老代中。年老代中存放的都是一些生命周期较长的对象。当老年代内存满时触发Major GC 即 Full GC
,Full GC 发生频率比较低
,执行时间也是Minor GC的十倍以上
。在老年代的对象一般为:存活时间比较长的,还有就是比较大的对象。
永久代/元空间
Java8 以前永久代,受JVM 管理,java8 以后元空间,直接使用物理内存。
元空间位于堆外
,所以它的最大内存大小取决于系统内存,而不是堆大小,我们可以指定MaxMetaspaceSize
参数来限定它的最大内存。
GC回收流程
GC回收流程图
GC回收详细流程
当一个新对象创建时,首先会来到新生区的Eden区中,这里进行
第一次判断
:判断当前新对象是否可以再Eden区放得下,如果放下我们直接放到Eden区分配内存即可;如果放不下时,就要进行一次Minor GC
。此次GC我们展开来详细说一下:回收时进行第二次判断
:判断Survivor0是否放得下,如果放得下Eden 区存活对象复制到一个 Survivor0 区,然后清空 Eden 区,当这个 Survivor0 区也存放满了时,则将 Eden 区和 Survivor0 区存活对象复制到另一个 Survivor1 区,然后清空 Eden 和这个 Survivor0 区,此时 Survivor0 区是空的,然后将 Survivor0 区和 Survivor1 区交换,即保持 Survivor1 区为空, 如此往复(对照上面两个区域来回切换)。当对象在 Survivor 区躲过一次 GC 的话,其对象年龄便会加 1,此时进行第三次判断
:判断年龄是否达到阈值,默认情况下,如果对象年龄达到 15 岁。超过就会移动到老年代中。不超则继续在Survivor。(对照上图虚线框)
执行完Minor GC
后,进行第四次判断
:判断Eden区是否放得下,如果放得下就进行内存分配,如果放不下默认作为大对象放到老年区
。此时进行第五次判断
新对象是否在老年区放得下,如果放得下就进行内存分配;如果放不下则进行一次Major GC 即 Full GC(执行时间为Minor GC的10倍多)
,最后进行第五次判断
:判断老年区是否放得下,如果放得下进行内存分配;放不下则直接报异常OOM
,此时需要改变堆的内存大小了。
-Xmx:最大堆大小
-Xms:初始堆大小
查看JDK自带可视化堆空间图
1. Win + R 输入jvisualvm
2. 安装GC插件
3. 查看内存图
总结
这样一个大的面试题就描述完成了,主要是理解GC回收的流程懂了,堆的结构也就知道怎么回事了。
参考文章: 文章地址
随便推广一下自己的网站!!!
【高频Java面试题】简单说说JVM堆的内存结构和GC回收流程的更多相关文章
- 70道阿里百度高频Java面试题(框架+JVM+多线程+算法+数据库)
基础与框架 1.String类能被继承吗,为什么 2.String,Stringbuffer,StringBuilder的区别? 3.ArrayList和LinkedList有什么区别 4.类的实例化 ...
- 巩固java(二)----JVM堆内存结构及垃圾回收机制
前言: 我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构 ...
- JVM堆外内存随笔
一 JVM堆外内存 1)java与io(file,socket)的操作都需要堆外内存与jvm内存进行互相拷贝,因为操作系统是不懂jvm的内存结构的(jvm的内存结构是自管理的),所以堆外内存存放的是操 ...
- JVM初探- 使用堆外内存减少Full GC
JVM初探-使用堆外内存减少Full GC 标签 : JVM 问题: 大部分主流互联网企业线上Server JVM选用了CMS收集器(如Taobao.LinkedIn.Vdian), 虽然CMS可与用 ...
- 解Bug之路-记一次JVM堆外内存泄露Bug的查找
解Bug之路-记一次JVM堆外内存泄露Bug的查找 前言 JVM的堆外内存泄露的定位一直是个比较棘手的问题.此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤 ...
- 一次完整的JVM堆外内存泄漏故障排查记录
前言 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指令和工具分享,希望对大家有所帮助. 在整个排查过程中,我也走了不少弯路,但是在文章中我 ...
- 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控
如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...
- JVM内存模型及GC回收算法
该篇博客主要对JVM内存模型以及GC回收算法以自己的理解和认识做以记录. 内存模型 GC垃圾回收 1.内存模型 从上图可以看出,JVM分为 方法区,虚拟机栈,本地方法栈,堆,计数器 5个区域.其中最为 ...
- (转载)JVM中的内存模型与垃圾回收
转载自微信公众号:Java高级架构(Java-jiagou)-----看完这篇文章,我奶奶都知道JVM中的内存模型与垃圾回收了! 六.内存模型 6.1 内存模型与运行时数据区 Java虚拟机在执行J ...
随机推荐
- No shutdown animation in the electricity display only 1%
低电量自动关机时无关机动画 低电量自动关机时无关机动画1. 问题描述2. 分析3. solution4. 总结 1. 问题描述 DEFECT DESCRIPTION: No shutdown anim ...
- MCU软件最佳实践——矩阵键盘驱动
1.矩阵键盘vs独立按键 在mcu应用开发过程中,独立按键比较常见,但是在需要的按键数比较多时,使用矩阵键盘则可以减少io占用,提高系统资源利用率.例如,某mcu项目要求有16个按钮,如果采用独立按键 ...
- 新设备关联Gitlab
新设备关联Gitlab 1:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果 ...
- C# app.config 保存和读取例子
保存: Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath); if ...
- thanos的日志能不能打到文件里面去?
不行. thanos/pkg/logging/logger.go: logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) if logF ...
- MySQL的MyISAM与InnoDB的索引方式
在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式. MyISAM索引实现 MyISAM引擎使用B+Tr ...
- 🏆【Alibaba中间件技术系列】「Nacos技术专题」服务注册与发现相关的原理分析
背景介绍 前几篇文章介绍了Nacos配置中心服务的能力机制,接下来,我们来介绍Nacos另一个非常重要的特性就是服务注册与发现,说到服务的注册与发现相信大家应该都不陌生,在微服务盛行的今天,服务是非常 ...
- centos7 查看开机启动项
使用 systemctl list-unit-files 查看开机启动项 systemctl is-enabled redis.service 是否开机启动
- elasticsearch启动错误解决办法
1.max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] 解决: [r ...
- MySQL数据类型操作(char与varchar)
目录 一:MySQL数据类型之整型 1.整型 2.验证不同类型的int是否会空出一个存储正负号 3.增加约束条件 去除正负号(unsigned) 二:浮点型 1.浮点型 2.验证浮点型精确度 三:字符 ...