Day802.JVM热点问题 -Java 性能调优实战

news2024/11/18 6:43:43

JVM部分热点问题

Hi,我是阿昌,今天学习JVM部分热点问题的内容。

1、字符串常量不是在java8中已经被放入到堆中了吗,应该不在方法区中了,咋一些图中还在方法区中?

JVM 的内存模型只是一个规范,方法区也是一个规范,一个逻辑分区,并不是一个物理空间,这里说的字符串常量放在堆内存空间中,是指实际的物理空间。


2、JDK1.8中类的元数据是放在元数据区还是方法区呢?

元空间是属于方法区的,方法区只是一个逻辑分区,而元空间是具体实现。

所以类的元数据是存放在元空间,逻辑上属于方法区。


3、栈上分配这里,对局部变量对象的大小是否有要求,毕竟栈的内存比较小?

目前 Hotspot 虚拟机暂时不支持栈上分配对象

这其实是因为由于HotSpot虚拟机目前的实现导致栈上分配实现比较复杂。

栈上分配影响

  1. java只有值传递,跨方法的局部变量在栈上分配的话,在现有栈实现上
    会影响栈的回收。
  2. 栈属于线程所有,实现栈上分配,会消耗更多的内存。让java的多线程更
    吃内存。
  3. 如果实现栈上分配,还需要GC作用会弱化很多吧。
  4. 基类型栈上分配+引用类型堆分配

->全栈上分配。这么实现的话hotspot全推翻了。


4、G1 是如何实现更好的 GC 性能的吗?

CMS 垃圾收集器是基于标记清除算法实现的,目前主要用于老年代垃圾回收。

CMS 收集器的 GC 周期主要由 7 个阶段组成,其中有两个阶段会发生 stop-the-world,其它阶段都是并发执行的。

在这里插入图片描述

G1 垃圾收集器是基于标记整理算法实现的,是一个分代垃圾收集器,既负责年轻代,也负责老年代的垃圾回收。

跟之前各个分代使用连续的虚拟内存地址不一样,G1 使用了一种 Region 方式对堆内存进行了划分,同样也分年轻代、老年代,但每一代使用的是 N 个不连续的 Region 内存块,每个 Region 占用一块连续的虚拟内存地址。

在 G1 中,还有一种叫 Humongous 区域,用于存储特别大的对象。

G1 内部做了一个优化,一旦发现没有引用指向巨型对象,则可直接在年轻代的 YoungGC 中被回收掉。

在这里插入图片描述

G1 分为 Young GC、Mix GC 以及 Full GC。G1 Young GC 主要是在 Eden 区进行,当 Eden 区空间不足时,则会触发一次 Young GC。

将 Eden 区数据移到 Survivor 空间时,如果 Survivor 空间不足,则会直接晋升到老年代。此时 Survivor 的数据也会晋升到老年代。Young GC 的执行是并行的,期间会发生 STW。

当堆空间的占用率达到一定阈值后会触发 G1 Mix GC(阈值由命令参数 -XX:InitiatingHeapOccupancyPercent 设定,默认值 45),Mix GC 主要包括了四个阶段,其中只有并发标记阶段不会发生 STW,其它阶段均会发生 STW。

在这里插入图片描述
G1 和 CMS 主要的区别在于

  • CMS 主要集中在老年代的回收,而 G1 集中在分代回收,包括了年轻代的 Young GC 以及老年代的 Mix GC;
  • G1 使用了 Region 方式对堆内存进行了划分,且基于标记整理算法实现,整体减少了垃圾碎片的产生;
  • 在初始化标记阶段,搜索可达对象使用到的 Card Table,其实现方式不一样。

Card Table,在垃圾回收的时候都是从 Root 开始搜索,这会先经过年轻代再到老年代,也有可能老年代引用到年轻代对象,如果发生 Young GC,除了从年轻代扫描根对象之外,还需要再从老年代扫描根对象,确认引用年轻代对象的情况。这种属于跨代处理,非常消耗性能。为了避免在回收年轻代时跨代扫描整个老年代,CMS 和 G1 都用到了 Card Table 来记录这些引用关系。

只是 G1 在 Card Table 的基础上引入了 RSet,每个 Region 初始化时,都会初始化一个 RSet,RSet 记录了其它 Region 中的对象引用本 Region 对象的关系。除此之外,CMS 和 G1 在解决并发标记时漏标的方式也不一样,CMS 使用的是 Incremental Update 算法,而 G1 使用的是 SATB 算法。

首先,要了解在并发标记中,G1 和 CMS 都是基于三色标记算法来实现的:

  • 黑色:根对象,或者对象和对象中的子对象都被扫描;
  • 灰色:对象本身被扫描,但还没扫描对象中的子对象;
  • 白色:不可达对象。

基于这种标记有一个漏标的问题,也就是说,当一个白色标记对象,在垃圾回收被清理掉时,正好有一个对象引用了该白色标记对象,此时由于被回收掉了,就会出现对象丢失的问题。

为了避免上述问题,CMS 采用了 Incremental Update 算法,只要在写屏障(write barrier)里发现一个白对象的引用被赋值到一个黑对象的字段里,那就把这个白对象变成灰色的。而在 G1 中,采用的是 SATB 算法,该算法认为开始时所有能遍历到的对象都是需要标记的,即认为都是活的。

G1 具备 Pause Prediction Model ,即停顿预测模型。用户可以设定整个 GC 过程中期望的停顿时间,用参数 -XX:MaxGCPauseMillis 可以指定一个 G1 收集过程的目标停顿时间,默认值 200ms。

G1 会根据这个模型统计出来的历史数据,来预测一次垃圾回收所需要的 Region 数量,通过控制 Region 数来控制目标停顿时间的实现。


5、minor gc是否会导致stop the world?

不管什么 GC,都会发送 stop-the-world,区别是发生的时间长短。

而这个时间跟垃圾收集器又有关系,Serial、PartNew、Parallel Scavenge 收集器无论是串行还是并行,都会挂起用户线程,而 CMS 和 G1 在并发标记时,是不会挂起用户线程的,但其它时候一样会挂起用户线程,stop the world 的时间相对来说就小很多了。


6、major gc什么时候会发生,它和full gc的区别是什么?

Major Gc 在很多参考资料中是等价于 Full GC 的,我们也可以发现很多性能监测工具中只有 Minor GC 和 Full GC。一般情况下,一次 Full GC 将会对年轻代、老年代、元空间以及堆外内存进行垃圾回收。

触发 Full GC 的原因

  • 当年轻代晋升到老年代的对象大小,并比目前老年代剩余的空间大小还要大时,会触发 Full GC;
  • 当老年代的空间使用率超过某阈值时,会触发 Full GC;
  • 当元空间不足时(JDK1.7 永久代不足),也会触发 Full GC;
  • 当调用 System.gc() 也会安排一次 Full GC。

7、minor gc回收之后eden区存活对象的多少

jmap-heap pid在图中只能看年轻代parallel gc看不到老年代的是什么垃圾回收器对于提问cms垃圾回收器还是分老年代和年轻代回收分多个阶段有和程序并行的阶段也有stop the world阶段回收一整块老年代时间比较久,而gc把年轻代和老年代也有划分,不过拆成一个region了,对region的回收成本低,而且会判断那些region回收的对象更多,而且cms要经过多次full gc才可能把不用的内存归还给操作系统而g1只需要一次full gc就可以可以通过 jstat -gc pid interval 查看每次 GC 之后,具体每一个分区的内存使用率变化情况。

可以通过 JVM 的设置参数,来查看垃圾收集器的具体设置参数,使用的方式有很多,例如 jcmd pid VM.flags 就可以查看到相关的设置参数。

在这里插入图片描述

各个设置参数对应的垃圾收集器图表。

在这里插入图片描述


8、当第一次创建对象的时候eden空间不足会进行一次minor gc把存活的对象放到from s区。如果这个时候from s放不下。会发生一次担保进入老年代吗?当一次创建对象的时候eden空间不足进入from s区。当第二次创建对象的时候eden空间又不足了,这个时候会把,eden和第一次存在from s区的对象进行gc存活的放在tos区,tos区空间不足,进行担保放入老年代?

前提是老年代有足够接受这些对象的空间,才会进行分配担保。

如果老年代剩余空间小于每次 Minor GC 晋升到老年代的平均值,则会发起一次 Full GC。


10、AdaptiveSizePolicy这个参数是不是不太智能啊?我项目4G内存默认开启的AdaptiveSizePolicy。发现只给年轻代分配了136M内存。平时运行到没啥问题,没到定时任务的点就频繁FGC。每次定时任务执行完,都会往老年代推40多M,一天会堆300多M到老年代,也不见它把年轻代调大。用的parNew+CMS。后来把年轻代调整到1G(单次YGC耗时从20ms增加到了40ms),每天老年代内存涨20M左右。

创建对象占用的内存使用率,合理分配内存,并不仅仅考虑对象晋升的问题,还会综合考虑回收停顿时间等因素。针对某些特殊场景,可以手动来调优配置。


11、如何避免threadLocal内存池泄漏呢

ThreadLocal 是基于 ThreadLocalMap 实现的,这个 Map 的 Entry 继承了 WeakReference,而 Entry 对象中的 key 使用了 WeakReference 封装,也就是说 Entry 中的 key 是一个弱引用类型,而弱引用类型只能存活在下次 GC 之前。

如果一个线程调用 ThreadLocal 的 set 设置变量,当前 ThreadLocalMap 则会新增一条记录,但由于发生了一次垃圾回收,此时的 key 值就会被回收,而 value 值依然存在内存中,由于当前线程一直存在,所以 value 值将一直被引用。

这些被垃圾回收掉的 key 就会一直存在一条引用链的关系:Thread --> ThreadLocalMap–>Entry–>Value。

这条引用链会导致 Entry 不会被回收,Value 也不会被回收,但 Entry 中的 key 却已经被回收的情况发生,从而造成内存泄漏。我们只需要在使用完该 key 值之后,将 value 值通过 remove 方法 remove 掉,就可以防止内存泄漏了。


12、请问一下老师内存泄露和内存溢出具体有啥区别

内存泄漏是指不再使用的对象无法得到及时的回收,持续占用内存空间,从而造成内存空间的浪费。例如,Java6 中 substring 方法就可能会导致内存泄漏。当调用 substring 方法时会调用 new string 构造函数,此时会复用原来字符串的 char 数组,而如果我们仅仅是用 substring 获取一小段字符,而在原本 string 字符串非常大的情况下,substring 的对象如果一直被引用,由于 substring 里的 char 数组仍然指向原字符串,此时 string 字符串也无法回收,从而导致内存泄露。

内存溢出则是发生了 OutOfMemoryException,内存溢出的情况有很多,例如堆内存空间不足,栈空间不足,还有方法区空间不足等都会导致内存溢出。内存泄漏与内存溢出的关系:内存泄漏很容易导致内存溢出,但内存溢出不一定是内存泄漏导致的。


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

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

相关文章

Fiddler基础使用

目录预备知识关于web的一些基础知识实验目的实验环境实验步骤一实验步骤二实验步骤三预备知识 关于web的一些基础知识 要分析Fiddler抓取的数据包,我们首先要熟悉HTTP协议。HTTP即超文本传输协议,是一个基于请求/响应模式的、无状态的、应用层的协议&a…

【Python开发】Flask项目的组织架构

Flask项目的组织架构在大型Flask项目中,主要有三种常见的项目组织架构:功能式架构(也就是 Bluelog 程序使用的架构)、分区式架构和混合式架构。我们将以一个示例程序 myapp 作为示例来介绍这三种架构的特点和区别,这个…

教你用HTML+CSS实现百叶窗动画效果

推荐学习专栏: 【JavaWeb】Web前端JavaWeb学习专栏 文章目录前言1、百叶窗效果2、原理讲解3、制作百叶窗4、资源下载5、完整代码总结前言 我们浏览网页的时候总能看见一些炫酷的特效,比如百叶窗效果,本文我们就用HTMLCSS制作一个百叶窗小项…

副业该怎么选择,适合新手的四个副业项目,零基础也可操作的兼职

副业有可能有时挣得并不多,但它是一个改变未来的好机会。假如玩的开了,盈利并不比你工资少。95%的人自主创业也是从第二职业做起,做着干着就全职的了。 四个全员第二职业,新手如何做到单月9000,深入分析看下文&#xf…

license授权服务器

项目介绍 为软件提供授权制的使用方式,license申请端可以为产品生成license授权文件,集成了flowable工作流,经审批后生成license文件。 然后导入到服务端。客户端与服务端netty通信。实时判断license是否合法,从而使软件得到安全…

辣椒辣素修饰卵清蛋白 Capsaicin-ova,苍耳亭偶联鸡卵白蛋白 Xanthatin-ovalbumin

产品名称:辣椒辣素修饰卵清蛋白 英文名称: Capsaicin-ova 用途:科研 状态:固体/粉末/溶液 产品规格:1g/5g/10g 保存:冷藏 储藏条件:-20℃ 储存时间:1年 辣椒碱又称辣椒辣素&#xf…

抓包工具总结对照【fiddler F12 Charles wireshark】

本文主要对比fiddler Charles wireshark,纯手敲制作,动动小手点赞 文章目录抓包fidderF12开发者工具wiresharkCharles下载安装使用web抓包APP 抓包IOSAndroidCharles过滤弱网测试篡改数据修改请求数据重复发送请求Compose编辑接口服务器压力测试本地映射…

前端:Node.js遇到的错误整理

node.js当前错误汇总:错误1npm WARN config global --global, --local are deprecated. Use --locationglobal instead.原因:初步判断是node.js版本问题解决方法:错误2npm WARN logfile could not create logs-dir: Error: EPERM: operation …

MySQL主从复制最全教程(CentOS7 yum)

一、MySQL主从复制介绍 (1)MySQL数据库默认是支持主从复制的,不需要借助于其他的技术,我们只需要在数据库中简单的配置即可。 (2)MySQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自…

在Docker里安装FastDFS分布式文件系统详细步骤

安装需要的软件包 yum install -y yum-utils 设置yum源 yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo 安装docker yum install -y docker-ce 查看docker版本验证安装是否成功 docker -v 启动docker systemctl start d…

C++ 实用指南

C 发展得非常快!例如,C 标准的页数从 C98/03 的 879 页增加到了 C20 的 1834 页,多了近 1000 页!更重要的是,C 每次修订后,我们都会获得几十个新特性。你需要学习所有这些东西才能写出好代码吗?…

【计算机毕业设计】旅游网站ssm源码

下载链接:https://download.csdn.net/download/licongzhuo/87051535https://download.csdn.net/download/licongzhuo/87051535 一、系统截图(需要演示视频可以私聊) 摘 要 随着人民生活水平的提高,旅游业已经越来越大众化,而旅游业的核心是信息,不论是…

Redis数据结构之——跳表skiplist

写在前面 以下内容是基于Redis 6.2.6 版本整理总结 一、跳表(skiplist) 如何理解跳表?在了解跳表之前,我们先从普通链表开始,一点点揭开跳表的神秘面纱~ 首先,普通单链表来说,即使链表是有序…

第2-3-4章 上传附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss

文章目录5.3 接口开发-上传附件5.3.1 接口文档5.3.2 代码实现5.3.3 接口测试5.3 接口开发-上传附件 第2-1-2章 传统方式安装FastDFS-附FastDFS常用命令 第2-1-3章 docker-compose安装FastDFS,实现文件存储服务 第2-1-5章 docker安装MinIO实现文件存储服务-springboot整合minio…

MindMaster思维导图及亿图图示会员 超值获取途径

MindMaster思维导图及亿图图示会员 超值获取途径 会员九折优惠方法分享给大家!如果有需要,可以上~ 以下是食用方法: MindMaster 截图 亿图图示 截图 如果需要MindMaster思维导图或者亿图图示会员,可按照如下操作领取超值折扣优惠…

SaaS系统平台赋能大健康产业互联网变革,助力企业提升市场占有率

当前,数字化浪潮正在重塑大健康产业。随着全国多个重要省市的数字医疗、数字医保等措施正火热展开,我国大健康产业的数字化转型进程正在提速,这也为新一轮的行业洗牌带来新的发展机遇。 大健康产业数字化转型痛点:传统医疗信息化…

消息队列之kafka

1.先部署zookeeper集群 2.了解zookeeper 分布式服务系统框架:存储业务服务节点的元数据及状态信息并 负责通知zookeeper上注册服务节点给客户端 一、Zookeeper 概述 官方下载地址:archive.apache.org/dist/zookee… 1.1 Zookeeper 定义 Zookeeper…

使用KNN进行手写体识别和iris数据集分类

文章目录手写体识别iris数据集分类手写体识别 首先使用load_digits将数据加载,这里的数据集有1797个样本,前1384个训练数据而后面的413个样本作为测试集,每个数据集中的样本是8*8像素的图像和一个[0, 9]整数的标签。紧接着输出64个样本的图像…

【Egg从基础到进阶】二:安装本地Mysql

什么是数据库: 数据库是用于将数据持久化存储的一个容器,并且在这个容器处于云端,而不是像游览器的本地存储一样,数据只是针对你当前所在游览器。游览器的存储是一对一的。而线上数据库的存储是一对多的,或者是多对多的…

被欧美公司垄断近 20 年,中国工业软件的机会在哪里?

【CSDN 编者按】工业软件,又被称之为是现代工业体系的“大脑”。近年来,在政府、企业、从业者等各方的齐心协力之下,中国工业软件市场规模不断壮大,逐渐成为“制造大国”。然而,站在全球的角度来看,相较一些…