jvm新生代调优

5-4 新生代调优

只有排除了自己代码的问题后,再进行内存调优,内存调优都是从新生代开始,因为新生代优化空间更大一些

  1. 新生代的特点
  1. 所有的new操作分配内存都是非常廉价的,非常快

TLABthread-local allocation buffer(可防止多个线程创建对象时的干扰)

每个线程都在Eden区中分配私有的区域,即TLAB;

当new一个对象时,首先检查TLAB缓冲区中是否有可用内存,如果有,会优先在这一块空间进行对象的分配。之所以这么做,因为对象的分配也有线程安全的问题:比如线程1需要使用这段内存,在分配还没结束的过程中,线程2也要用这段内存,就会造成内存的分配混乱。因此在做对象的内存分配时,也要做一个线程的并发安全的保护,当然这个操作是由jvm做的

能否减少线程之间对内存分配的并发冲突呢?可以使用TLAB线程分配局部缓冲区,他的作用就是使用自己私有的伊甸园内存进行对像的分配,这样的话,多个线程即使同时创建对象,也不会产生对内存占用的干扰。所以伊甸园区创建对象效率时非常高的

  1. 死亡对象回收零代价

学过的所有的垃圾回收器,在新生代垃圾回收采用的都是复制算法

复制算法是将伊甸园和from中存活对象复制到to中,然后释放伊甸园和from所有内存,所以说死亡对象回收零代价

  1. 大部分对象用过即死(朝生夕死)

新生代垃圾回收,绝大部分用过即死,只有少部分存货下来

  1. MInor GC 所用时间远小于Full GC

MinorGC的时间与FullGC的时间相差1-2个数量级别

  1. 新生代内存越大越好么?

-Xmn :设置新生代的初始和最大值

新生代进行调优,有的人认为就是将新生代进行调大,这是一个最有效的方式,但是也要注意新生代在调大的过程中存在的问题

Sets the initial and maximum size (in bytes) of the heap for the young generation (nursery). GC is

performed in this region more often than in other regions. If the size for the young generation is

too small, then a lot of minor garbage collections are performed. If the size is too large, then only

full garbage collections are performed, which can take a long time to complete. Oracle

recommends that you keep the size for the young generation greater than 25% and less than

50% of the overall heap size.

  1. 太小

不是越大越好

新生代内存太小:频繁触发Minor GC,会STW,会使得吞吐量下降

如果设置小了,可用空间少,创建新对象时,一旦发现新生代空间不足,就会触发MinorGC,会产生STW,产生短暂的暂停

  1. 太大

新生代内存太大老年代内存占比有所降低堆空间一定前提下新生代认为空闲空间很多,新创建的对象不会触发GC。但是老年代的空间紧张,再触发垃圾回收,就是FullGC了。FullGC的STW要比MinorGC更长。如果新生代过大,引发的垃圾回收类型可能就是FullGC就需要占用更长的时间才能完成垃圾回收。会更频繁地触发Full GC。而且触发Minor GC时,清理新生代所花费的时间会更长

oracle给的建议是:堆的25%<新生代<堆的50%

  1. 吞吐量与新生代大小的关系

 

实际生产过程中,随着新生代的增加,吞吐量会有一个拐点,新生代如果设置的太小会引发的缺点,以及这个新生代如果。原因是新生代比较大,造成回收时间的变长

  1. 新生代大小

新生代内存设置为能容纳[并发量*(一次请求-响应所产生的对象)]的数据为宜

但是总的原则啊,我们还是要将新生代调的尽可能大。你刚才不是。还说啊,新生代的空间大了,那将来这个垃圾回收的时间变长了?但是我们刚才还有一个因素没有考虑进去。什么因素呢?就是新生代垃圾的回收都是复制算法。算法也是分成两个阶段,第1个阶段标记,第2个阶段呢去进行复制,那么这两个阶段哪个阶段花费的时间更多一些呢,其实是复制。因为复制牵扯到这个对象的占用内存块移动。另外呢你要更新对象引用的地址,这个速度相对更耗时一些。而新生代的对象,大家想想啊绝大部分都是朝生夕死的,也就是说最终只有少量的对象啊,只有少量的对象会存活下来的,所以既然是少量的对象存货,那它复制所占用的时间其实也是相对较短的,而标记时间,相对于复制时间来讲,显得不是那么重要,所以我们新生代调大的情况下。因为主要耗费的时间还是在复制上。即使增的很大效率也不会有特别明显的下降,这是对新生代大小设置的一个补充。

那究竟把它设成多大比较合适呢?我们的一个理想情况是,我的一个新生代能够容纳请求和响应过程中一次请求和响应过程中所产生的对象乘上并发量。举一个例子,比如说我一次请求响应的过程中呢,可能会创建很多新的对象,那这些新的对象加起来大约呢,比如说占到了512K的内存,那这是我的并发量呢,大概是1000。也就是,同一时刻,有1000个用户来访问我。这时候我的新生代,它的一个比较理想的内存就是。每一个请求响应乘以我的并发量,也就是512k×1000,大约是512M。为什么我们设成这么大就比较理想呢?这是因为你这一次请求响应的过程以后,其中大部分对象都会被回收。只要你这一次请求加上你的并发量所占用内存不超过我新生代的内存,它就不会触发。或较少的触发新生代的垃圾回收。这样就可以大约估算出新生代内存占用到底划分成多少比较合理。

  1. 幸存区大小

幸存区大到能保留【当前活跃对象+需要晋升对象】

新生代还有一块区域,我们称之为叫幸存区。幸存区呢,它的内存设置要遵从这么几个规则。

第1个呢,就是我们要考虑到幸存区啊,它也要足够的大,大到呢,能够保留当前的活跃对象和需要晋升的对象。这是什么意思呢?解释一下啊,幸存区中,你可以把它看成有两类对象:第1类对象呢,它是生命周期较短,也许下一次垃圾的时候就要把它回收掉了,但是由于现在还正在使用,它暂时不能回收,所以它就留在我们的幸存区中;另一类呢是他肯定将来会被晋升到老年的 ,因为大家都在用它,但是由于年龄还不够,所以暂时还存活在幸存区当中,没有被晋升。那幸存区中呢,就可以看成是这两类对象,存储的都是这两类对象。一类是马上就要被回收的一类是将来肯定要晋升的

那幸存区呢,你的大小就得大到把这两类对象都能够容纳。为什么这么说?这里要提到幸存区的一个晋升规则如果幸存区比较小,它就会由jvm动态的去调整你的这个晋升的阈值。也许你本来有一些对象,轮不到他晋升,它的寿命还不够,但是由于幸存区的内存太少,导致提前把一些对象晋升到老年代区。也许是刚才我们说的这种存活时间较短的对象,提前被晋升到了老年代,那这样有什么问题呢?或者说有什么缺点呢,就是如果你本来一个存活时间短的对象被晋升到了老年代,那就意味着,他得等到老年代内存不足时触发Full GC时才能把它当成垃圾进行回收。所以这就是变相的延长了这个对象的生存的时间。这是一个不太好的地方。我们最好能实现,就是这种存活时间短的,在下次新生代的垃圾回收里就把它回收掉了。真正需要,长时间存活的对象,我才把它晋升到老年代,这是一条规则。

  1. 晋升阈值

晋升阈值配置得当,让长时间存活对象尽快晋升

-XX:MaxTenuringThreshold=threshold  调整最大晋升阈值

-XX:+PrintTenuringDistribution

 

事物呢还是都有两面性,那么我们一方面希望的是存活时间短的对象让他留在幸存区,以便下一次垃圾回收能把它回收掉;而另一方面呢,我们又希望这个长时间存活的对象,他应该尽快的被晋升

为什么这么说呢,因为如果你是一个长时间存活的对象,你把它留在幸存区里,只能够浪费我们幸存区的这个内存,并且呢,因为我们的新生代垃圾回收都是复制算法,要把这个幸存区中的这些对象,下次存活了又要把它进行复制复制,从from复制到to,我们前面也说过,那么这个新生代复制算法主要的耗费时间就是在这个对象的复制上,如果有大量的这些长时间存活的对象,他们不能及早的晋升,那么他们就相当于留在这个幸存区,被复制来复制去,这样呢,对我的性能其实反而是一个负担。所以遇到这种情况呢就要设置一下它的晋升阈值,把晋升阈值调的比较小,让这些长时间存活的对象呢,能够尽快的晋升到老年代区。这个参数:-XX:MaxTenuringThreshold=threshold  可以调整最大晋升阈值。

有的时候我们还需要把它晋升的一些详细信息显示出来,便于我去判断到底应该把晋升阈值设置为多少更为比较合适,相关的参数是下面这个参数:-XX:+PrintTenuringDistribution 这个参数呢,带上以后它就会在每次垃圾回收时把survival幸存区中的这些存活对象、详情显示出来。第一列,就是它的一个对象的年龄我们可以从这个事例中看到,年龄为1的,是刚逃过一次MinorGCC的这个对象,它占用的空间大小是多少;年龄2的对象在这个幸存区中的对象占用了多少的空间;为3的占用空间是多少这是年龄为1、2、3的对象各自占用空间数,后面是他们的累计总和数——空间占用的累计总和,比如说12加起来是3058888,123加起来是31784800。通过每次把这个幸存区中不同年龄的对象它所占用的空间打印,我们可以更细致的去决定到底把最大的晋升阈值调成多少比较合适,让那些长时间存在的影响能够尽早的晋升。这就是对新生代内存调优的一个说明。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis——基础篇(包含redis在云服务上的docker化安装和连接以及常用命令)

初识Redis Redis为键值型数据库&#xff0c;数据以键值形式存储。没有表&#xff0c;没有约束。 认识NoSQL mysql就是典型的关系型数据库(SQL)。 目的都是数据的增删改查&#xff0c;但数据存储方式不一样。 关系型和非关系型在结构上有差异 关系型的结构一般定好后就很少修…

【JAVAEE】JVM中垃圾回收机制 GC

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 上篇文章我们讲了java运行时内存的各个区域。 传送门&#xff1a;【JavaEE】JVM的组成及类加载过程_xyk:的博客-CSDN博客 对于程序计数器、虚拟机栈、本地方法栈这三部分区域而言&#x…

动态规划01背包之1049 最后一块石头的重量 II(第9道)

题目&#xff1a; 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 。那么粉碎的可能结果如下&#xff1a; …

微信小程序(二)

目录 1、input标签 一、表单绑定 1、数据绑定 2、输入获取 二、网络请求 1、介绍 2、注意 3、使用 4、基于Promise封装 三、自定义组件 1、创建 2、父向子组件通信 3、子向父组件通信 4、生命周期 四、vant weapp组件库 1、配置 2、使用 进入本章前的拓展&#…

Git❀详细使用教程

Git❀详细使用教程 一、Git简介1.1 什么是Git&#xff1f;1.2 Git的特点1.3 集中式与分布式的区别&#xff1f;1.4 Git工作流程图 二、Git安装与常用命令2.1 Git环境配置2.1.1 下载与安装2.1.2 基本配置2.1.3 为常用指令设置别名&#xff08;可选&#xff09;2.1.4 解决GitBash…

jsonschema networknt json-schema-validator 高级能力json 数字很大时, 变成什么类型

入参校验产品化 schema_个人渣记录仅为自己搜索用的博客-CSDN博客 自动变成了bigInteger类型. 哪怕你的jsonSchema 配置的是integer , 不冲突.

AlGaN基深紫外FP激光器仿真模型及材料信息数据库有何用途?

波长范围为UVC波段&#xff08;100-280 nm&#xff09;的深紫外FP&#xff08;Fabry-Pero&#xff0c;法布里和珀罗是两位法国的科学家&#xff09;激光器可广泛应用于数据通信、光通信、3D打印、材料加工、显示与照明、激光雷达、人脸/手势识别、医疗和表面监测等领域。FP激光…

2023年Q2京东冰箱行业品牌销售排行榜(京东销售数据分析)

近年我国的冰箱零售呈波动变化的趋势&#xff0c;由于冰箱市场趋于饱和&#xff0c;因此消费者对冰箱的需求逐渐变为替换需求&#xff0c;这也进一步推动了产品的更新迭代。接下来结合具体数据&#xff0c;我们来分析一下2023年Q2冰箱行业的销售详情。 根据鲸参谋电商数据分析平…

SpringBoot+Vue实现的高校图书馆管理系统

项目描述&#xff1a;这是一个基于SpringBootVue框架开发的高校图书馆管理系统。首先&#xff0c;这是一个前后端分离的项目&#xff0c;代码简洁规范&#xff0c;注释说明详细&#xff0c;易于理解和学习。其次&#xff0c;这项目功能丰富&#xff0c;具有一个高校图书馆管理系…

6.2.5 网络基本服务----动态主机配置协议DHCP

6.2.5 网络基本服务----动态主机配置协议DHCP 动态主机配置协议允许一台计算机加入新的网络时可自动获取网络配置信息&#xff0c;不用人工参与。连网的计算机需要配置的参数包括 IP地址子网掩码默认路由器的IP地址域名服务器IP地址 DHCP与DNS、FTP、Telnet一样也采用客户服…

Lua脚本本地调试

这里主要使用日志的方式进行debug 环境依赖 项目对openresty包的依赖比较高&#xff0c;所以环境基础都在openresty下进行 openresty的使用 openresty下载地址 下载完成后解压&#xff0c;具体使用方式和nginx没有什么区别&#xff0c;主要依赖文件是一下几个 nginx.exe …

搬家送货小程序开发源码定制一键报警实时定位路线规划

1.货物信息录入&#xff1a; 用户可以输入货物的名称、数量、重量、尺寸等信息。 2.路线选择&#xff1a; 用户可以选择起始地点和目的地点&#xff0c;并根据需求选择最佳路线。 提供地图服务或第三方路径规划服务&#xff0c;以帮助用户确定最佳路线。 3.车辆选择&#…

基于深度学习的高精度鸡蛋检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度鸡蛋检测识别系统可用于日常生活中或野外来检测与定位鸡蛋目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的鸡蛋目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型…

跨域问题解决

由于同源策略&#xff0c;需要协议&#xff0c;域名&#xff0c;端口三个都相同才能进行访问&#xff0c;是一种浏览器的保护策略 CORS:Cross Origin Resource Sharing SpringBoot 项目中解决跨域 1.在目标方法中加入CrossOrigin注解 2.添加一种过滤器 分别是允许哪些域&#…

ffmpeg2段视频合成一段

查看分辨率 帧率和编码器 ffprobe -v error -select_streams v:0 -show_entries streamcodec_name,width,height,avg_frame_rate -of defaultnoprint_wrappers1 rs2.mp4得到&#xff0c;编码器&#xff0c;分辨率&#xff0c;还有帧率 codec_nameh264 width1920 height1080 avg…

Linux 发行版 Gentoo 存在重大漏洞

网络安全公司 SonarSource 在日前研究中发现&#xff0c;Gentoo Linux 发行版中存在漏洞 CVE-2023-28424&#xff0c;黑客可以利用该漏洞进行 SQL 注入攻击。 研究人员从 GentooLinux 的 Soko 搜索组件中找到了这个漏洞。该漏洞的 CVSS 风险评分为 9.1&#xff0c;属于特别重大…

Flutter 仿抖音、豆瓣、知乎、番茄小说的评论弹窗开发实践

最近用flutter做了一个评论弹窗的功能&#xff0c;本来以为很简单的烂大街的一个功能&#xff0c;结果却遇到了不少的问题&#xff0c;而且这些问题我觉得很有意义&#xff0c;以至于我觉得我如果分享出来可能会对其他人很有帮助。 要做一件事情可能会很容易&#xff0c;但做好…

springboot之配置文件加载

springboot启动流程参考。Springboot总结。本内容主要解析里面的配置文件的加载过程。 springboot资源加载 入口。SpringApplication#run 我们知道&#xff0c;run方法是构建容器的过程。里面有一个方法&#xff1a;prepareEnvironment。用于构建环境组件Environment&#xf…

cocos2d-js中jsc逆向为js

1.下载脚本https://github.com/tablis/jsc-decompile-mozjs-34 2.安装php7以上的版本 ubuntu $ sudo apt install php7.0 mac $ brew install php7.0 windows just google an binary one 查看php安装的版本这里mac电脑为例子: 输入:php -v 只要7以上的版本即可 3.cd到…

http协议(二)

欢迎来到南方有乔木的博客&#xff01;&#xff01;&#xff01; 博主主页&#xff1a;点击点击&#xff01;戳一戳&#xff01;&#xff01; 博主名:南方有乔木呀 博主简介&#xff1a; 一名在校大学生&#xff0c;正在努力学习Java语言编程。穷且意坚&#xff0c;不坠青云…