JVM 相关知识点记录

文章目录

  • 前言
  • 哪些内存需要回收
  • 方法区的垃圾回收
  • 垃圾收集算法
  • 垃圾收集器
  • 年轻代进入老年代条件
  • 内存担保机制
  • FullGC 触发时机
  • GC日志解析
    • 日志参数


前言

JVM包含内容:

  • 类装载子系统(Class Load SubSystem)
  • 运行时数据区(Run-Time Data Areas)
      • 局部变量表
      • 操作数栈
      • 动态链接
      • 方法返回地址
    • 程序计数器
    • 方法区
  • 本地方法接口(Native Method Stack)
  • PC寄存器(Programe Counter Register)
  • 执行引擎(Execution Engine)
    • 字节码解释器
      对字节码采用逐行解释的方式执行
    • JIT(Just In Time)编译器

JIT(Just In Time)编译器

  • 方法调用计数器:统计方法调用次数
    统计方法调用的次数。默认阈值时Client模式下1500次,在Server模式下是10000次。超过这个阈值就会触发JIT编译。这个阈值可以通过-XX:CompileThreshold设定
  • 回边计数器:统计循环体执行的循环次数

jvm内存分配

  • 栈上分配与TLAB/内存分配的两种方法

jdk1.8默认垃圾回收器
JDK1.8中,Parallel Scavenge 被设置为年轻代(Young Generation)的默认垃圾回收器,而 Parallel Old 是用于老年代(Tenured Generation)的垃圾回收器

哪些内存需要回收

所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象。
寻找回收对象的两种方式。

  • 引用计数法
    给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失效时,计数器值-1。任何时刻计数值为0的对象就是不可能再被使用的。
  • 可达性分析法
    通过一系列称为GC Roots的对象作为起始点,从这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的。

可以作为GCRoots的对象包括下面几种:

  • 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。
  • 方法区中的类静态属性引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI(Native方法)引用的对象。

方法区的垃圾回收

方法区的垃圾回收主要回收两部分内容:

  1. 废弃常量。
    以字面量回收为例,如果一个字符串“abc”已经进入常量池,但是当前系统没有任何一个String对象引用了叫做“abc”的字面量,那么,如果发生垃圾回收并且有必要时,“abc”就会被系统移出常量池。常量池中的其他类(接口)、方法、字段的符号引用也与此类似。
  2. 无用的类。既然进行垃圾回收,就需要判断哪些是废弃常量,哪些是无用的类,需要满足以下三个条件:
    • 该类的所有实例都已经被回收,即Java堆中不存在该类的任何实例。
    • 加载该类的ClassLoader已经被回收。
    • 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

垃圾收集算法

  • 标记-清除(Mark-Sweep)算法
  • 复制(Copying)算法
  • 标记-整理(Mark-Compact)算法
  • 分代收集算法

垃圾收集器

  • Serial收集器()
    需要STW(Stop The World),停顿时间长。
    简单高效,对于单个CPU环境而言,Serial收集器由于没有线程交互开销,可以获取最高的单线程收集效率。
  • Serial Old收集器
    Serial收集器的老年代版本
  • ParNew收集器
    ParNew收集器其实就是Serial收集器的多线程版本
  • Parallel Scavenge收集器
  • Parallel Old收集器
  • CMS收集器
  • G1收集器

垃圾收集器讲解

垃圾收集器讲解2

年轻代进入老年代条件

  • 躲过15次gc,达到15岁高龄之后进入老年代;
  • 动态年龄判定规则,如果Survivor区域内年龄1+年龄2+年龄3+年- 龄n的对象总和大于Survivor区的50%,此时年龄n以上的对象会进入老年代,不一定要达到15岁
  • 如果一次Young GC后存活对象太多无法放入Survivor区,此时直接计入老年代
  • 大对象直接进入老年代

内存担保机制

  1. 什么是老年代空间担保机制?担保的过程是什么?
    JVM有这么一个参数:-XX:-HandlePromotionFailure(1.8默认设置)
      年轻代每次GC前都,JVM都会计算老年代剩余可用空间,如果这个剩余空间小于年轻代里所有对象大小之和(包括垃圾对象),那么JVM就会看是否设置前面这个参数。如果设置这个参数,且老年代剩余空间是否小于之前每一次MInorGC后进入老年代对象的平均大小。
      如果没设置参数,或者小于平均大小,会先触发一次FullGC,将老年代和年轻代的垃圾对象一起回收掉,如果回收后还是没有空间存放对象,则会发生OOM。

在这里插入图片描述

  1. 老年代空间担保机制是谁给谁担保?
    我理解的是老年代给新生代的S区做担保。
  2. 为什么要有老年代空间担保机制?或者说空间担保机制的目的是什么?
    目的:避免频繁的进行FullGC。
  3. 如果没有老年代空间担保机制会有什么不好?
    如果没有这个担保机制,就会直接执行Full GC,这样对性能的影响频次会增加。

FullGC 触发时机

Full GC(Full Garbage Collection)是指对整个Java堆进行垃圾回收,包括新生代和老年代。触发Full GC的情况有以下几种:

  • 老年代空间不足:当老年代中没有足够的空间来分配一个大对象时,会先尝试进行Minor GC,如果仍然无法获得足够的空间,则会触发Full GC。

  • 调用System.gc()方法:虽然使用System.gc()方法不能保证立即进行垃圾回收,但是这个方法可以提示JVM进行垃圾回收。如果此时需要更多的内存空间,那么就可能会触发Full GC。

  • Perm区空间不足:Perm区是存放类信息和常量池等元数据的区域,如果Perm区没有足够的空间来存放这些信息,就会触发Full GC。

  • CMS GC出现Concurrent Mode Failure:CMS(Concurrent Mark Sweep)是一种以最小化停顿时间为目标的垃圾收集器,在CMS执行过程中,如果应用程序产生了大量更新,导致CMS回收速度跟不上对象生成速度,那么就可能会出现Concurrent Mode Failure,此时会启动Full GC来清理整个堆空间。

  • 分配担保失败:在Minor GC后,如果survivor区无法容纳所有幸存对象,那么就要将部分幸存对象转移到老年代。如果老年代剩余空间不足以容纳这些对象,就需要进行Full GC。

需要注意的是,Full GC通常比Minor GC和CMS GC的停顿时间长,同时对于大型应用程序,Full GC可能会影响性能,因此应该尽量避免Full GC的发生。

GC日志解析

GC日志内容

日志内容解析及GC案例

不同垃圾收集器的不同日志打印示例
G1垃圾收集器日志解析

日志参数

  • -XX:+PrintGC: 输出GC日志。类似:java -verbose:gc
  • -XX:+PrintGCDetails : 输出GC的详细日志
  • -XX:+PrintGCTimestamps : 输出GC的时间戳(以基准时间的形式)
  • -XX:+PrintGCDatestamps : 输出GcC的时间戳(以日期的形式,如2013-05-04T21:53:59.234+0800)
  • -XX:+PrintHeapAtGC: 在进行GC的前后打印出堆的信息
  • -Xloggc:./logs/gc.log: 日志文件的输出路径

-XX:+PrintGC :

这个只会显示总的GC堆的变化,如下:

[GC (Allocation Failure) 80832K->19298K(227840K),0.0084018 secs]
[GC (Metadata GC Threshold) 109499K->21465K(228352K),0.0184066 secs]
[Full GC (Metadata GC Threshold) 21465K->16716K(201728K),0.0619261 secs]

参数解析:

GCFull GCGC的类型,GC只在新生代上进行,Full GC包括永生代,新生代,老年代。
Allocation FailureGC发生的原因。
80832K->19298K:堆在GC前的大小和GC后的大小。
228840k:现在的堆大小。
0.0084018 secs:GC持续的时间。

-XX:+PrintGCDetails

[GC (Allocation Failure) [PSYoungGen:70640K->10116K(141312K)] 80541K->20017K(227328K),0.0172573 secs] [Times:user=0.03 sys=0.00,real=0.02 secs]
[GC (Metadata GC Threshold) [PSYoungGen:98859K->8154K(142336K)] 108760K->21261K(228352K),0.0151573 secs] [Times:user=0.00 sys=0.01,real=0.02 secs]
[Full GC (Metadata GC Threshold)[PSYoungGen:8154K->0K(142336K)]
[ParOldGen:13107K->16809K(62464K)] 21261K->16809K(204800K),[Metaspace:20599K->20599K(1067008K)],0.0639732 secs]
[Times:user=0.14 sys=0.00,real=0.06 secs]

参数解析:

GCFull FC:同样是GC的类型
Allocation FailureGC原因
PSYoungGen:使用了Parallel Scavenge并行垃圾收集器的新生代GC前后大小的变化
ParOldGen:使用了Parallel Old并行垃圾收集器的老年代GC前后大小的变化
Metaspace: 元数据区GC前后大小的变化,JDK1.8中引入了元数据区以替代永久代
xxx secs:指GC花费的时间
Times:user:指的是垃圾收集器花费的所有CPU时间sys:花费在等待系统调用或系统事件的时间real:GC从开始到结束的时间,包括其他进程占用时间片的实际时间。

-XX:+PrintGCTimestamps & -XX:+PrintGCDatestamps

带上日期:

2019-09-24T22:15:24.518+0800: 3.287: [GC (Allocation Failure) [PSYoungGen:136162K->5113K(136192K)] 141425K->17632K(222208K),0.0248249 secs] [Times:user=0.05 sys=0.00,real=0.03 secs]2019-09-24T22:15:25.559+0800: 4.329: [GC (Metadata GC Threshold) [PSYoungGen:97578K->10068K(274944K)] 110096K->22658K(360960K),0.0094071 secs] [Times: user=0.00 sys=0.00,real=0.01 secs]
2019-09-24T22:15:25.569+0800: 4.338: [Full GC (Metadata GC Threshold) [PSYoungGen:10068K->0K(274944K)][ParoldGen:12590K->13564K(56320K)] 22658K->13564K(331264K),[Metaspace:20590K->20590K(1067008K)],0.0494875 secs] [Times: user=0.17 sys=0.02,real=0.05 secs]

总结 :

[GC[Full GC说明了这次垃圾收集的停顿类型,如果有Full则说明GC发生了"Stop The World"

不同的垃圾收集器在日志中的名称:

  • 使用Serial收集器在新生代的名字是Default New Generation,因此显示的是[DefNew
  • 使用ParNew收集器在新生代的名字会变成[ParNew,意思是Parallel New Generation
  • 使用Parallel Scavenge收集器在新生代的名字是[PSYoungGen
  • 使用Parallel Old收集器收集器在老年代显示[ParoldGen
  • 使用G1收集器的话,会显示为garbage-first heap

Allocation Failure:表明本次引起GC的原因是因为在年轻代中没有足够的空间能够存储新的数据了。
Metadata GCThreshold:Metaspace区不够用了
FErgonomics:JVM自适应调整导致的GC
System:调用了System.gc()方法

一般日志格式:

GC日志格式的规律一般都是:GC前内存占用->GC后内存占用(该区域内存总大小)

[PSYoungGen:5986K->696K(8704K) ] 5986K->704K(9216K)

  • 中括号内:GC回收前年轻代大小,回收后大小,(年轻代总大小)
  • 括号外:GC回收前年轻代和老年代大小,回收后大小,(年轻代和老年代总大小)

GC日志中有三个时间:user,sys和real

  • user:进程执行用户态代码(核心之外)所使用的时间。这是执行此进程所使用的实际CPU 时间,其他进程和此进程阻塞的时间并不包括在内。在垃圾收集的情况下,表示GC线程执行所使用的 CPU 总时间。
  • sys:进程在内核态消耗的 CPU 时间,即在内核执行系统调用或等待系统事件所使用的CPU 时间
  • real:程序从开始到结束所用的时钟时间。这个时间包括其他进程使用的时间片和进程阻塞的时间(比如等待 I/O 完成)。对于并行gc,这个数字应该接近(用户时间+系统时间)除以垃圾收集器使用的线程数。

日志分析原文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/745390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

某赛通电子文档安全管理系统 DecryptApplication 任意文件读取漏洞(2024年3月发布)

漏洞简介 某赛通电子文档安全管理系统 DecryptApplication 接口处任意文件读取漏洞,未经身份验证的攻击者利用此漏洞获取系统内部敏感文件信息,导致系统处于极不安全的状态。 漏洞等级高危影响版本*漏洞类型任意文件读取影响范围>1W 产品简介 …

数据结构 day4 链表

1: 2: 3: 4: 5: 6:

C#,动态规划问题中基于单词搜索树(Trie Tree)的单词断句分词( Word Breaker)算法与源代码

1 分词 分词是自然语言处理的基础,分词准确度直接决定了后面的词性标注、句法分析、词向量以及文本分析的质量。英文语句使用空格将单词进行分隔,除了某些特定词,如how many,New York等外,大部分情况下不需要考虑分词问题。但有些情况下,没有空格,则需要好的分词算法。…

CSS 3

CSS3现状 在CSS2的基础上新增(扩展)样式移动端支持优于PC端不断改进中应用相对广泛 1.CSS3属性选择器 选择符简介E[att]选择具有att属性的E元素E[att"val"]选择具有att属性且属性值等于val的E元素E[att^"val"]匹配具有att属性、且具有以val开头的E元素E…

AJAX 01 AJAX 概念和 axios 使用

2.27 AJAX 学习 AJAX 1 入门01 AJAX 概念和 axios 使用axios 使用案例 02 认识 URLURL组成 03 URL 查询参数axios-查询参数案例 :地区查询 04 常用请求方法和数据提交axios 请求配置axios 错误处理 05 HTTP协议-报文① 请求报文作用:错误排查…

数据结构:堆

堆的概念 1.堆是一个完全二叉树 2.小堆(任何一个父亲<孩子),大堆(任何一个父亲>孩子) 堆的结构 物理结构:数组 逻辑结构:二叉树 #pragma once #include<assert.h> #include<iostream> typedef int HPDataType; typedef struct Heap {HPDataType* _a;int…

使用 Jenkins 管道在 Docker Hub 中构建 Docker 镜像

Jenkins Pipeline 是一个强大的工具&#xff0c;可以自动执行部署。在各个阶段之间拆分的灵活和自定义操作是尝试此功能的一个很好的理由。 构建您自己的 Docker 镜像并将其上传到 Docker Hub 以保持存储库更新是了解 Jenkins Pipeline 如何改进您的工作方式的一个很好的示例。…

产品推荐 - 基于Xilinx Kintex-7 XC7K160T/325T/410T打造的水星Mercury+ KX2核心板

水星Mercury KX2核心板 水星Mercury KX2核心板提供高性价比的Xilinx Kintex-7 28nm FPGA和常见的接口&#xff0c;如USB 2.0、PCIe Gen2和千兆以太网。 KX1有强大的FPGA和标准接口、很多具备LVDS能力的I/O、大容量DDR3 SDRAM、很多高速DSP slices&#xff0c;它既适合高端数字信…

第五十八回 吴用赚金铃吊挂 宋江闹西岳华山-飞桨图像分割套件PaddleSeg初探

鲁智深被贺太守抓住&#xff0c;押入死牢。武松得信后&#xff0c;正想回梁山报信&#xff0c;正好戴宗来了&#xff0c;就请戴宗赶快回梁山搬救兵。宋江说兄弟有难&#xff0c;怎能不救&#xff1f; 于是带了十六个头领来到少华山。 因为华州城池厚壮&#xff0c;宋江等无计可…

【开源】SpringBoot框架实验室耗材管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗材出库模块2.4 耗材申请模块2.5 耗材审核模块 三、系统展示四、核心代码4.1 查询耗材品类4.2 查询资产出库清单4.3 资产出库4.4 查询入库单4.5 资产入库 五、免责说明 一、摘要 1.1…

JavaEE之多线程(创建线程的五种写法)详解

&#x1f63d;博主CSDN主页: 小源_&#x1f63d; &#x1f58b;️个人专栏: JavaEE &#x1f600;努力追逐大佬们的步伐~ 目录 1. 前言 2. 操作系统"内核" 3. 创建线程的五种写法 (我们重点要掌握最后一种写法!!) 3.1 继承 Thread, 重写 run 3. 2 实现 Runnabl…

电脑坏了去维修,第一家报价800,第三家说报废!

这篇文章主要讲的是修理坏掉的电脑。 第一家报价300&#xff0c;第二家报价800&#xff0c;第三家说要报废&#xff01; 相信很多朋友对于修电脑坏了要多少钱有很多困惑&#xff0c;修电脑坏了要多少钱&#xff0c;到底去正规售后服务还是去非品牌店维修一台坏掉的电脑。 今天高…

Jmeter扩展---自定义取样器

简介 Jmeter已经内置了各种协议的取样器&#xff0c;已经能满足常用的性能压测需求。且在前面一章Jmeter扩展开发--自定义java取样器-CSDN博客中也有关于Java取样器的扩展开发&#xff0c;不过有时候我们期望能定制自己的取样器和界面。为此&#xff0c;需要对Jmeter做扩展&am…

界面控件DevExpress ASP.NET Scheduler - 助力快速交付个人信息管理系统(下)

DevExpress ASP. NET Scheduler组件能完全复制Microsoft Outlook Scheduler的样式和功能&#xff0c;具有日、周、月和时间轴视图&#xff0c;并包括内置的打印支持&#xff0c;因此用户可以在尽可能短的时间内交付全功能的个人信息管理系统。在上文中&#xff08;点击这里回顾…

Gemma中RoPE代码详细讲解

最近在看Gemma代码感觉比LLama的代码看的方便点&#xff0c; 看到RoPE代码跟常规的方式不太一样&#xff08;也不算常规&#xff0c;就是我理解的方式&#xff09;&#xff0c;特此记录一下。我的RoPE入门代码参考&#xff1a;Rotary Position Embedding (RoPE, 旋转式位置编码…

自然语言处理实验2 字符级RNN分类实验

实验2 字符级RNN分类实验 必做题&#xff1a; &#xff08;1&#xff09;数据准备&#xff1a;academy_titles.txt为“考硕考博”板块的帖子标题&#xff0c;job_titles.txt为“招聘信息”板块的帖子标题&#xff0c;将上述两个txt进行划分&#xff0c;其中训练集为70%&#xf…

服务器Debian 12.x中安装Jupyer并配置远程访问

服务器系统&#xff1a;Debian 12.x&#xff1b;IP地址&#xff1a;10.100.2.138 客户端&#xff1a;Windows 10;IP地址&#xff1a;10.100.2.38 利用ssh登录服务器&#xff1a; 1.安装python3 #apt install python3 2.安装pip #apt install python3-pip … 3.安装virtualen…

Unity Timeline学习笔记(3) - SignalTrack信号轨道和自定义带参数的Marker信号和轨道

信号轨道&#xff0c;顾名思义就是运行到某处发送一个信号。 普通用法 普通用法就是没有任何封装的&#xff0c;个人感觉特别难用&#xff0c;但是有必要理解一下工作原理。 添加信号 我们添加一个信号资源 生成后可以看到资源文件&#xff0c;这个是可以拖到SignalTrack上…

【Python数据结构与判断7/7】数据结构小结

目录 序言 整体回忆 定义方式 访问元素 访问单个元素 访问多个与元素 修改元素 添加元素 列表里添加元素 字典里添加元素 删除元素 in运算符 实战案例 总结 序言 今天将对前面学过的三种数据结构&#xff1a;元组&#xff08;tuple&#xff09;、列表&#xff08;…

微前端框架 qiankun 配置使用【基于 vue/react脚手架创建项目 】

qiankun官方文档&#xff1a;qiankun - qiankun 一、创建主应用&#xff1a; 这里以 vue 为主应用&#xff0c;vue版本&#xff1a;2.x // 全局安装vue脚手架 npm install -g vue/clivue create main-app 省略 vue 创建项目过程&#xff0c;若不会可以自行百度查阅教程 …