一、概念

1、JVM组成及作用

(1)组成:类加载器、运行时数据区(Java内存模型)、执行引擎、本地库接口

(2)作用:

类加载器(ClassLoader)把class文件转换成字节码;

运行时数据区(Runtime Data Area)把字节码加载到内存中;

特定的命令解析器执行引擎(Execution Engine),将内存中的字节码翻译成底层系统指令,再交由 CPU去执行

调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。

2、内存模型JMM/运行时数据区

(1)组成

线程共享:堆、方法区(非堆,内存元空间,包括常量池)/永久代

线程私有:栈(虚拟机栈、本地方法栈)、程序计数器

(2)线程共享

a. 堆(GC堆):存放对象实例,是垃圾回收器的区域,可以细分为新生代和老年代;

更好地进行内存分配与回收,可以划分为多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB),存储的依旧是对象实例。

堆在逻辑上连续,物理上不连续,大小可固定可扩展。

堆中无法完成实例分配且无法扩展时,会抛出OOM(OutOfMemoryError)异常/内存溢出。

堆中一个空对象大小占8字节byte

b. 方法区:存储被JVM加载的常量、静态变量、类信息、即时编译代码等数据。

JVM中将其描述为堆的一个逻辑部分,也被称为非堆(Non-Heap)。

又可以分为运行时常量池和直接内存。

(3)线程独享

a. 程序计数器:当前线程所执行字节码的行号指示器

可以完成程序的分支、循环、跳转、异常处理、线程恢复等基础功能

为了便于多线程切换时能恢复到正确的执行位置,不会出现OOM

b. 栈:存放基本类型和堆中对象的引用

可以分为虚拟机栈和本地方法栈

虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,本地方法栈为虚拟机使用到的Native方法服务

可能会抛出StackOverflowError异常/栈溢出

一个对象只对应了一个4字节的引用(堆栈分离的好处)

3、为什么要进行堆栈分离

栈代表了处理逻辑,而堆代表了数据,分开使得处理逻辑更为清晰

堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象),栈中只需要记录堆的地址。

提供了一种有效的数据交互方式(如:共享内存),也可以节省内存

栈固定,而堆可以根据需要动态增长

4、对象的访问定位方式

使用句柄:堆中会划分出句柄池,池中存储对象的句柄地址,句柄中包含数据的具体地址

直接指针:存储类型和数据,修改时需要变两次指针

二、垃圾回收

1、判断可以回收的方法

引用计数法

可达性分析算法

2、从哪回收

由栈指向堆,从堆中回收

3、标为垃圾的对象会回收吗

不一定,至少经历两次标记

第一次标记:可达性分析后没有引用链,就会被标记

第二次标记:筛选没有重新与引用链建立联系的对象,进行第二次标记,执行finalize()方法,并进行回收;如果在finalize()方法中重新与引用链建立关联,则逃离本次回收,继续存活。

4、引用概念

引用分为强引用、软引用、弱引用、虚引用,四种引用强度依次减弱。

强引用:永不被回收

软引用:有用但非必须,内存溢出前进行回收,并将其加入引用队列

弱引用:只要被GC线程扫描到,就会被回收

虚引用:随时被回收,用于对象被回收时收到系统通知

5、垃圾回收算法

标记-清除(Mark-Sweep):会造成内存碎片

复制算法(Copying):有用的复制到另一边

标记-整理(Mark-compact):存活对象移动到最左端,解决内存碎片问题

分代收集:大部分JVM采取,划分为新生代、老年代,以及非堆的永久代(方法区)

6、为什么使用分代收集

(1)对象的生命周期不同,针对不同对象,采用不同收集方式,可以提高回收效率

(2)如String对象等临时变量,有些甚至一次回收;Session对象与业务挂钩,生命周期长

7、新生代Young回收

(0)Minor GC,频率高,无需等到eden区满后才触发,主要采用Copying算法

(1)新生成的对象均放在年轻代,目标是收集生命周期短的对象

(2)按8:1:1的比例分为eden区和两个survivor区(survivor0、survivor1)

复制清空

先将对象生成到eden区,回收时将存活对象复制到survivor0区,然后清空eden区;

当survivor0区存满时,将eden区和survivor0区存活对象复制到survivor1区,并清空eden区和survivor0区,并将survivor0区和survivor1区交换,保持survivor1区为空;

(3)当 survivor1 区不足以存放 Eden 区 和 survivor0区的存活对象时,将存活对象放至老年代;

(4)老年代满了,就会触发一次Full GC(major GC),同时回收新生代和老年代

8、老年代回收

(1)年轻代经历N次回收后仍然存活的对象(生命周期较长),就会进入老年代

(2)老年代内存是新生代的一倍,老年代对象存活率比较高

6、浮动垃圾

GC线程和工作线程并行运行,在垃圾回收过程中产生的垃圾,就产生了浮动垃圾,这些垃圾在下次垃圾回收时才能被回收

7、内存碎片

不同对象存活时间不同,不进行内存整理,就会出现内存碎片

复制和标记整理算法,均可以解决碎片问题

8、常见的垃圾回收器

(1)Serial(Old)串行收集器-单线程

使用复制算法,是client默认的方式

通过 -XX:+UseSerialGC 来强制指定

(2)ParNew收集器-多线程

ParNew:Serial的多线程版本

(3)Parallel Scavenge-高吞吐量的并行收集器

使用停止-复制算法,是server级别的默认GC方式

使用-XX:+UseParallelGC强制指定,用-XX:ParallelGCThreads=4指定线程数

(4)Parallel Old收集器-并行收集器

Parallel 收集器的老年代版本

(5)CMS(Concurrent Mark Sweep)收集器-并发收集器(同时开始工作)

使用标记-清除算法

以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器

加上“-XX:+UseConcMarkSweepGC”指定

注意:产生大量碎片,剩余内存无法运行,出现Concurrent Mode Failure

临时CMS采用Serial Old回收器进行垃圾清除,此时的性能将会被降低

(6)G1(Garbage-First)-分区模型

将内存分为多个Region

后台维护优先列表,根据收集时间,选择回收价值最大的Region

(7)〇暂停ZGC(Zero pause GC)

采用颜色指针,根据颜色指针决定是否做相应操作

从根开始找

标记位标记指针的状态,初始标记为M0

有M0就是有用的,没有 M0,是remapped就是垃圾

线程访问M0时,对应对象的标记就会换成M0

8、CMS垃圾回收器

(1)含义

Concurrent Mark-Sweep,并发标记-清除,以牺牲吞吐量为代价来获得最短回收停顿时间

(2)过程

初始标记:快速记录与root直接相连的对象,暂停其他线程;

并发标记:GC和用户线程同时开始,由于不断更新引用域,闭包内不能包含所有的可达对象,会记录引用更新位置;

重新标记:修正引用更新的位置,

并发清除:对未标记区域进行清扫

9、G1垃圾回收器

(1)分区:把整个堆划分为一个一个等大小的区域(region)。内存的回收和划分都以region为单位

(2)支持分代的垃圾回收

(3)区域优先:收集那些活跃对象小的 region,以便快速回收空间

10、垃圾回收策略/时机

(1)新生代的Minor / Scavenge GC

Eden区满后触发新生代的 Minor GC

Eden区不会分配很大,所以Eden区的GC会频繁进行

(2)老年代的Major GC-速度慢

何时会触发?

对于大对象,首先在Eden尝试创建,创建不了,就会触发Minor GC

随后继续尝试在Eden区存放,仍然放不下

尝试进入老年代,老年代也放不下

触发 Major GC 清理老年代的空间

(3)整个堆的Full GC

减少Full GC次数,对JVM的调优即对Full GC的调节

11、何时会导致Full GC

调用System.gc(),会建议虚拟机执行Full GC

大对象进入,导致老年代空间不足

永久代空间不足

空间分配担保失败:使用复制算法的 Minor GC 需要老年代的内存空间作担保,如果担保失败会执行一次 Full GC。

【面试题总结】JVM01-组成及垃圾回收的更多相关文章

  1. 面试题之C# 内存管理与垃圾回收

    面试题之C# 内存管理与垃圾回收 你说说C# 的内存管理是怎么样的 这句话我记了一个多礼拜了, 自从上次东北师大面试之后, 具体请看<随便扯扯东北师大的面试>. 国庆闲着没事, 就大概了解 ...

  2. 李洪强iOS经典面试题37-解释垃圾回收的原理

    李洪强iOS经典面试题37-解释垃圾回收的原理   问题 我们知道,Android 手机通常使用 Java 来开发,而 Java 是使用垃圾回收这种内存管理方式. 那么,ARC 和垃圾回收对比,有什么 ...

  3. 李洪强iOS经典面试题31-解释垃圾回收的原理

    李洪强iOS经典面试题31-解释垃圾回收的原理 问题 我们知道,Android 手机通常使用 Java 来开发,而 Java 是使用垃圾回收这种内存管理方式. 那么,ARC 和垃圾回收对比,有什么优点 ...

  4. JVM垃圾回收面试题

    Java垃圾回收有个经典面试题,什么时候,对什么对象,做了什么操作? 垃圾回收里涉及内容很多,要准确回答这个问题首先要先限定边界.分清楚虚拟机规范定义和不同虚拟机实现的差异.以工作中用到的hotspo ...

  5. 不止面试-JVM垃圾回收面试题详解

    第一部分:面试题 本次分享我们将尝试回答以下问题: GC 是什么? 为什么要有 GC? 简单说一下java的垃圾回收机制. JVM的常见垃圾回收算法有哪些? 为什么要使用分代回收机制? 如何判断一个对 ...

  6. 【搞定Jvm面试】 JVM 垃圾回收揭秘附常见面试题解析

    JVM 垃圾回收 写在前面 本节常见面试题 问题答案在文中都有提到 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好 ...

  7. JVM(十二),垃圾回收面试题

    十二.垃圾回收面试题 1.Object的finalize()方法 2.Java中的强软弱虚四种引用 (1)强引用 (2)软引用(间接引用) (3)弱引用 (4)虚引用 (5)四种引用区别

  8. .NET面试题系列[5] - 垃圾回收:概念与策略

    面试出现频率:经常出现,但通常不会问的十分深入.通常来说,看完我这篇文章就足够应付面试了.面试时主要考察垃圾回收的基本概念,标记-压缩算法,以及对于微软的垃圾回收模板的理解.知道什么时候需要继承IDi ...

  9. 面试题-Java基础-垃圾回收

    1.Java中垃圾回收有什么目的?什么时候进行垃圾回收? 垃圾回收的目的是识别并且丢弃应用不再使用的对象来释放和重用资源. 2.System.gc()和Runtime.gc()会做什么事情? 这两个方 ...

  10. 图解 CMS 垃圾回收机制原理,-阿里面试题

    最近在整理JVM相关的PPT,把CMS算法又过了一遍,每次阅读源码都能多了解一点,继续坚持. 什么是CMS CMS全称 ConcurrentMarkSweep,是一款并发的.使用标记-清除算法的垃圾回 ...

随机推荐

  1. OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构

    博主最近失业在家,找工作之余,看了一些关于洋葱(整洁)架构的资料和项目,有感而发,自己动手写了个洋葱架构解决方案,起名叫OnionArch.基于最新的.Net 7.0 RC1, 数据库采用Postgr ...

  2. 详解ROMA Connect API 流控实现技术

    摘要:本文将详细描述API Gateway流控实现,揭开高性能秒级流控的技术细节. 1.概述 ROMA平台的核心系统ROMA Connect源自华为流程IT的集成平台,在华为内部有超过15年的企业业务 ...

  3. 华为路由器vrrp(虚拟路由器冗余协议)基本配置命令

    vrrp(虚拟路由器冗余协议)基本配置 int g0/0/0 vrrp vrid 1 virtual-ip 172.16.1.254 创建VRRP备份组,备份组号为1,配置虚拟IP为172.16.1. ...

  4. windows下cmd补全键注册表修改

      1:使用win+r打开 运行 控制台 2:输入 regedit 打开注册表 3:进入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\ ...

  5. 亚马逊云 RDB数据故障转移(多可用区)

    RDB关系数据库(Relational Database,RDB) 创建名为VPC for RDS的vpc 两个可用区,两组公内网 创建安全组 创建RDS数据库实例用的数据库子网组 创建RDS数据库实 ...

  6. 什么是ForkJoin?看这一篇就能掌握!

    摘要:ForkJoin是由JDK1.7之后提供的多线程并发处理框架. 本文分享自华为云社区<[高并发]什么是ForkJoin?看这一篇就够了!>,作者: 冰 河. 在JDK中,提供了这样一 ...

  7. Debian 参考手册之第6章Debian档案库

    来源:https://www.debian.org/doc/manuals/debian-faq/ftparchives#oldcodenames 第 6 章 Debian 档案库 目录 6.1. 有 ...

  8. vs自定义工程宏

    [视图] ---->[其他窗口]----> [属性管理器 ]右键工程---->[添加新项目属性表]打开配置debug/release打开propertysheet找到用户宏即可添加

  9. VBA工程设置密码

    VBA 工程设置密码 Alt + F11,进入程序界面: 工具---> VBAProject属性---> 保护---> 查看时锁定工程前打勾,并在下面的密码区输入密码.

  10. go:快速添加接口方法及其实现

    问题描述 在大型项目中,通常存在多个模块,模块对外暴露的功能通常是通过接口封装,这样可以明确模块的功能,有效降低模块与模块之间的耦合度,同时模块与模块之间进行合理的组装.接口的实现,有时可能存在多个实 ...