关于GC(中):Java垃圾回收相关基础知识

时间:2022-12-19 10:24:15

Java内存模型

关于GC(中):Java垃圾回收相关基础知识

(图源: 深入理解JVM-内存模型(jmm)和GC)

区域名 英文名 访问权限 作用 备注
程序计数器 Program Counter Register 线程隔离 标记待取的下一条执行的指令 执行Native方法时为空; JVM规范中唯一不会发生OutOfMemoryError的区域
虚拟机栈 VM Stack 线程隔离 每个Java方法执行时创建,用于存储局部变量表,操作栈,动态链接,方法出口等信息 方法执行的内存模型
本地方法栈 Native Method Stack 线程隔离 Native方法执行时使用 JVM规范没有强制规定,如Hotspot将VM和Native两个方法栈合二为一
Java堆 Java Heap 线程共享 存放对象实例 更好的回收内存 vs 更快的分配内存
方法区 Method Area 线程共享 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 JVM规范不强制要求做垃圾收集
运行时常量池 Runtime Constant Pool 线程共享 方法区的一部分
直接内存 Direct Memory - 堆外内存,通过堆的DirectByteBuffer访问 不是运行时数据区的一部分,但也可能OutOfMemoryError

对象的创建——new的时候发生了什么

讨论仅限于普通Java对象,不包括数组和Class对象。

  1. 常量池查找类的常量引用,如果没有先做类加载
  2. 分配内存,视堆内存是否是规整(由垃圾回收器是否具有压缩功能而定)而使用“指针碰撞”或“空闲列表”模式
  3. 内存空间初始化为零值,可能提前在线程创建时分配TLAB时做初始化
  4. 设置必要信息,如对象是哪个类的示例、元信息、GC分代年龄等
  5. 调用<init>方法

垃圾回收器总结

垃圾回收,针对的都是堆。

分代

  • 新生代:适合使用复制算法, 以下三个区一般占比为8:1:1
    • Eden 新对象诞生区
    • From Survivor 上一次GC的幸存者(见“GC种类-minor GC”)
    • To Survivor 本次待存放幸存者的区域
  • 老年代:存活时间较久的,大小较大的对象,因此使用标记-整理或标记-清除算法比较合适
  • 永久代:存放类信息和元数据等不太可能回收的信息。Java8中被元空间(Metaspace)代替,不再使用堆,而是物理内存。

分代的原因

  • 不同代的对象生命周期不同,可以针对性地使用不同的垃圾回收算法
  • 不同代可以分开进行回收

回收算法

名称 工作原理 优点 缺点
标记-清除 对可回收对对象做一轮标记,标记完成后统一回收被标记的对象 易于理解,内存利用率高 效率问题;内存碎片;分配大对象但无空间时提前GC
复制 内存均分两块,只使用其中一块。回收时将这一块存活对象全部复制到另一块 效率高 可用空间减少; 空间不够时需老年代分配担保
标记-整理 对可回收对对象做一轮标记,标记完成后将存活对象统一左移,清理掉边界外内存 内存利用率高 效率问题

标记-X算法适用于老年代,复制算法适用于新生代。

GC种类

  • Minor GC,只回收新生代,将Eden和From Survivor区的存活对象复制到To Survivor
  • Major GC,清理老年代。但因为伴随着新生代的对象生命周期升级到老年代,一般也可认为伴随着FullGC。
  • FullGC,整个堆的回收
  • Mixed GC,G1特有,可能会发生多次回收,可以参考关于G1 GC中Mixed GC的分析

垃圾回收器小结

垃圾回收器名称 特性 目前工作分代 回收算法 可否与Serial配合 可否与ParNew配合 可否与ParallelScavenge配合 可否与SerialOld配合 可否与ParallelOld配合 可否与CMS配合 可否与G1配合
Serial 单线程 新生代 复制 - - - Y N Y N/A
ParNew 多线程 新生代 复制 - - - N N Y N/A
ParallelScavenge 多线程, 更关注吞吐量可调节 新生代 复制 - - - N N Y N/A
SerialOld 单线程 老年代 标记-整理 - - - Y Y N N/A
ParallelOld 多线程 老年代 标记-整理 N N Y - - - N/A
CMS 多线程,并发收集,低停顿。但无法处理浮动垃圾,标记-清除会产生内存碎片较多 老年代 标记-清除 Y Y N Y - - N/A
G1 并行并发收集,追求可预测但回收时间,整体内存模型有所变化 新生代/老年代 整体是标记-整理,局部(两Region)复制 N N N N N N -

在本系列的上一篇文章关于GC(上):Apache的POI组件导致线上频繁FullGC问题排查及处理全过程中,减少FullGC的方式是使用G1代替CMS,计划在下一篇文章中对比CMS和G1的区别。

理解GC日志

只举比较简单的例子,具体各项的格式视情况分析,不同回收器也会有差异。

2019-11-22T10:28:32.177+0800: 60188.392: [GC (Allocation Failure) 2019-11-22T10:28:32.178+0800: 60188.392: [ParNew: 1750382K->2520K(1922432K), 0.0312604 secs] 1945718K->198045K(4019584K), 0.0315892 secs] [Times: user=0.09 sys=0.01, real=0.03 secs]

开始时间-(方括号[)-发生区域(ParNew,命名和GC回收器有关)-回收前大小-回收后大小-(方括号])-GC前堆已使用容量-GC后堆已使用容量大小-回收时间-使用时间详情(用户态时间-内核时间-墙上时钟时间)

注意这里没有包括“2019-11-22T10:28:32.177+0800: 60188.392: [GC (Allocation Failure)”这部分的分析。

可借鉴的编程模式

对象分配的并发控制

对象创建是很频繁的,在线程共享的堆中会遇到并发的问题。两种解决办法:

  1. 同步锁定:CAS+失败重试,确保原子性
  2. 堆中预先给每个线程划分一小块内存区域——本地线程分配缓冲(TLAB),TLAB使用完并分配新的TLAB时才做同步锁定。可看作1的优化。

CAS: Conmpare And Swap,用于实现多线程同步的原子指令。 将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。关于CAS可以参考:

Java中的CAS实现原理

CAS系列(3):CAS无锁自旋和同步锁线程切换使用场景对比

对象访问的定位方式

前提条件:通过上本地变量表的reference访问中的对象及它在方法区的对象类型数据(类信息)

主流的两种方式,这两种方式各有优点,可以看出方式2是方式1的优化,但并不是全面超越方式1,无法完全取代。

这里可以看到要权衡垃圾回收和访问速度两方面。

方式1: 直接指针访问实例数据

关于GC(中):Java垃圾回收相关基础知识

图源:深入理解JVM-内存模型(jmm)和GC

reference直接存放对象实例地址,只需要一次访问即可,执行效率较高。

方式2: 使用句柄池

关于GC(中):Java垃圾回收相关基础知识

图源:深入理解JVM-内存模型(jmm)和GC

reference中地址稳定,对象被移动时只需要改句柄池的地址。相对的,访问实例需要两次指针定位。

参考资料

  1. 周志明.著《深入理解JAVA虚拟机》
  2. 深入理解JVM-内存模型(jmm)和GC
  3. jvm的新生代、老年代、永久代关系
  4. JVM垃圾回收——新生代,老年代,永久代,Minor GC,Full GC

关于GC(中):Java垃圾回收相关基础知识的更多相关文章

  1. JVM垃圾回收的基础知识

    什么是垃圾? 没有任何引用指向的对象,就是垃圾 如何找到垃圾?(2 种方法) 过程:先找到正在使用的对象,然后把没有正在使用的对象进行回收 1.引用数-Reference-Count 被引用数为 0 ...

  2. JAVA面试题相关基础知识

        1.面向对象的特征有哪些方面 ①抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节 ...

  3. java OOP及相关基础知识汇总(转)

    OOP 对象有三个要素 behavior 接口是怎样的,有什么方法/field可以用? state 调用方法的时候,对象会有什么反应? 只有通过调用方法才能改变一个对象的state identity ...

  4. Java GC(垃圾回收)机制知识总结

    目录 Java GC系列 Java关键术语 Java HotSpot 虚拟机 JVM体系结构 Java堆内存 启动Java垃圾回收 Java垃圾回收过程 垃圾回收中实例的终结 对象什么时候符合垃圾回收 ...

  5. &lbrack;译&rsqb;Java垃圾回收是如何工作的

    说明:这篇文章来翻译来自于Javapapers 的How Java Garbage Collection Works 这部分教程是为了理解Java垃圾回收的基础以及它是如何工作的.这是垃圾回收系列教程 ...

  6. &lbrack;译&rsqb;Java 垃圾回收介绍

    说明:这篇文章来翻译来自于Javapapers 的Java Garbage Collection Introduction 在Java中,对象内存空间的分配与回收是由JVM中的垃圾回收进程自动完成的. ...

  7. 细述 Java垃圾回收机制&srarr;Types of Java Garbage Collectors

    细述 Java垃圾回收机制→Types of Java Garbage Collectors 转自:https://segmentfault.com/a/1190000006214497 本文非原创, ...

  8. Java基础知识强化83:System类之gc&lpar;&rpar;方法(垃圾回收)以及和finalize&lpar;&rpar;区别

    1. System概述: System类包含一些有用的类字段和方法.它不能被实例化. 2. gc()方法:垃圾回收器 public static void gc()       调用gc方法暗示着Ja ...

  9. Java GC系列(1):Java垃圾回收简介

    本文由 ImportNew - 好好先生 翻译自 javapapers. Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Ja ...

随机推荐

  1. jQuery 2&period;0&period;3 源码分析 数据缓存

    历史背景: jQuery从1.2.3版本引入数据缓存系统,主要的原因就是早期的事件系统 Dean Edwards 的 ddEvent.js代码 带来的问题: 没有一个系统的缓存机制,它把事件的回调都放 ...

  2. JSON&colon; Property &&num;39&semi;xxx&&num;39&semi; has no getter method的解决办法

    在使用JSONArray.fromObject时候出现JSONException:Property 'xxx' has no getter method. 解决办法:设置bean为public属性即可 ...

  3. php常见的面试题目

    一. 基本知识点1.1 HTTP协议中几个状态码的含义:503 500 401 403 404 200 301 302...200 : 请求成功,请求的数据随之返回.301 : 永久性重定向.302 ...

  4. xp的虚拟机如何访问本地主机上的文件

    1.选中虚拟机,右键选择Settings,在options选项卡里选择Shared Folders,然后在右边设置要共享的文件夹. 2.power on 虚拟机,然后在虚拟机的VM菜单中,选择“Ins ...

  5. 转:在MyEclipse下创建Java Web项目 入门(图文并茂)经典教程

    本文是一篇在Myeclipse下构建Java Web项目的初级教程.图文并茂,非常详细.所用的Myeclipse版本是7.5. 第一步:新建Web Project,如下图. 第二步,在弹出的窗口填写下 ...

  6. px&sol;em&sol;pt区别和转换

    老是被人问到px.pt和em的区别,自己有时候也会纠结到底该用什么单位,今天特意查了一些文章,下面这篇虽然很久远了,但解释的比较全面,转载收藏之.点击查看原文 这里引用的是Jorux的“95%的中国网 ...

  7. 实战Tomcat配置SSL,使用openssl制作证书

    制作证书以及Tomcat配置 搭建openssl环境,下载openssl并设置环境变量方便命令行的使用: 修改openssl配置文件,设置dir目录,如设置dir=e:/temp/openssl_ca ...

  8. C语言程序设计第二次作业——

    1,编译过程过程中的错误缺引号和分号并且拼写错误. 正确结果: 2,编译过程 改正错误: 正确结果: 3,利用SIZEOF运算符求出的数据类型所占字节大小: 4,在头文件LIMITS.H中相关的编译 ...

  9. Linux 桌面玩家指南:08&period; 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码

    特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之 ...

  10. oracle SQL多表查询

    SQL多表查询 1.集合理论 1.1 什么是集合 具有某种特定性质的事物的总体. 集合的特性:无序性.互异性.确定性. 一个集合可以小到从一个表中取出一行中的一列.              1 ro ...