jvm内存分配与回收策略

news/2025/1/15 19:00:42/

自动内存管理

解决两个问题

自动给对象分配内存

对象一般堆上分配(而实际上也有可能经过即时编译后被拆散为标量类型并间接地在栈上分配)

新生对象通常会分配在新生代,少数情况下(例如对象大小超过一定阈值)也可能会直接分配在老年代

实际对象分配的规则并不是固定的,具体取决于虚拟机使用的是哪一种垃圾收集器以及虚拟机中与内存相关参数的设定

自动回收分配给对象的内存(垃圾收集器做的事)

对象优先在Eden分配

大多数情况下,对象在新生代Eden区中分配当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。

-XX:+PrintGCDetails:收集器日志参数,告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前的内存各区域分配情况。

image-20230927232825248

参数含义:

-Xms20M(初始) -Xmx20M(最大):堆内存固定20m

-Xmn10M:10MB分配给新生代(剩下的10MB分配给老年代)

-XX:SurvivorRatio=8:新生代中Eden区与一个Survivor区的空间比例是8:1

代码:

public class AllocationTest {private static final int _1MB = 1024 * 1024;public static void main(String[] args) {byte[] a1, a2, a3, a4;a1 = new byte[2 * _1MB];a2 = new byte[2 * _1MB];a3 = new byte[2 * _1MB];a4 = new byte[4 * _1MB]; // 出现一次Minor GC}
}

控制台打印:

image-20230927234410189

上述老年代占用4M跟下一节阈值默认配置有关。

Minor GC、Major GC以及Full GC因为不同垃圾收集器以及不同JDK版本触发条件都不尽相同

Minor GC:新生代垃圾收集

Major GC:老年代垃圾收集

Full GC:全堆垃圾收集

思路基本都是内存不够用了进行垃圾收集

大对象直接进入老年代

大对象指需要大量连续内存空间的Java对象最典型的大对象便是那种很长的字符串,或者元素数量很庞大的数组

Java虚拟机中要避免大对象的原因

分配空间时,容易导致内存明明还有不少空间时就提前触发垃圾收集,以获取足够的连续空间才能安置好大对象,而当复制对象时,大对象意味着高额的内存复制开销

-XX:PretenureSizeThreshold:指定大于该设置值的对象直接在老年代分配(默认值为3145728字节即3M)

【-XX:PretenureSizeThreshold=3145728】,超过3MB的对象都会直接在老年代进行分配。

-XX:PretenureSizeThreshold参数仅在使用Parallel Scavenge(并行年轻代)和Parallel Old(并行老年代)【JDK8默认组合】收集器组合时以及Serial和ParNew两款新生代收集器有效。

长期存活的对象将进入老年代

HotSpot虚拟机中多数收集器都采用了分代收集来管理堆内存,那内存回收时就必须能决策哪些存活对象应当放在新生代,哪些存活对象放在老年代中。

虚拟机给每个对象定义了一个对象年龄(Age)计数器,存储在对象头中

对象通常在Eden区里诞生,如果经过第一次Minor GC后仍然存活,并且能被Survivor容纳,该对象会被移动到Survivor空间中,并且将其对象年龄设为1岁。对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15),就会被晋升到老年代中

-XX:MaxTenuringThreshold:设置对象晋升老年代的年龄阈值(默认15)

动态对象年龄判定

为了能更好地适应不同程序的内存状况,

HotSpot虚拟机并不是永远要求对象的年龄必须达到-XX:MaxTenuringThreshold才能晋升老年代

如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到-XX:MaxTenuringThreshold中要求的年龄。

空间分配担保

在发生Minor GC之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,大于则保证这次Minor GC是安全的,否则看参数-XX:HandlePromotionFailure:是否允许担保失败;如果允许,继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,大于,将尝试进行一次Minor GC,小于则进行一次Full GC。

JDK 6Update 24之后规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行Minor GC,否则将进行Full GC。(-XX:HandlePromotionFailure参数不会再影响到虚拟机的空间分配担保策略


http://www.ppmy.cn/news/1130193.html

相关文章

web:[ACTF2020 新生赛]Upload

题目 点进页面&#xff0c;是一个文件上传&#xff0c;能联想到getshell 先尝试随便上传一个文件试试 显示上传的文件以jpg、png、gif结尾的图片 构造一句话木马&#xff0c;再将文件后缀改为jpg <?php eval($_POST[1234]);?> 显示上传成功&#xff0c;但是显示无法…

软件测试中的测试工具和自动化测试

1. 测试工具 测试工具也分为不同人员使用的 开发人员&#xff1a;测试框架&#xff0c;编写测试用例&#xff1b;各类线上dump分析工具如windgb&#xff1b;开发时的集成IDE工具如Visual Studio&#xff0c;idea等等 面向不同测试需求的测试工具 软件测试是软件开发生命周期…

【RabbitMQ实战】07 3分钟部署一个RabbitMQ集群

一、集群的安装部署 我们还是利用docker来安装RabbitMQ集群。3分钟安装一个集群&#xff0c;开始。 前提条件&#xff0c;docker安装了docker-compose。如果没安装的话&#xff0c;参考这里 docker-compose文件参考bitnami官网&#xff1a;https://github.com/bitnami/contai…

ElementUI之登陆+注册->饿了吗完成用户登录界面搭建,axios之get请求,axios之post请求,跨域,注册界面

饿了吗完成用户注册登录界面搭建axios之get请求axios之post请求跨域注册界面 1.饿了吗完成用户注册登录界面搭建 将端口号8080改为8081 导入依赖&#xff0c;在项目根目录使用命令npm install element-ui -S&#xff0c;添加Element-UI模块 -g&#xff1a;将依赖下载node_glod…

24-25届最新计算机毕业设计大数据选题推荐 -大数据毕业设计题目参考大全

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

Linux编译器-gcc/g++使用和动静态库的对比

目录 1. 背景知识 2.安装g/gcc 2.1安装指令 2.2安装成功查看指令 3gcc如何完成 3.1预处理(进行宏替换) 3.2编译&#xff08;生成汇编&#xff09; 3.3汇编&#xff08;生成机器可识别代码&#xff09; 3.4连接&#xff08;生成可执行文件或库文件&#xff09; 3.5gcc选…

PyTorch 模型性能分析和优化 — 第 1 部分

一、说明 这篇文章的重点将是GPU上的PyTorch培训。更具体地说&#xff0c;我们将专注于 PyTorch 的内置性能分析器 PyTorch Profiler&#xff0c;以及查看其结果的方法之一&#xff0c;即 PyTorch Profiler TensorBoard 插件。 二、深度框架 训练深度学习模型&#xff0c;尤其是…

uniapp h5 端 router.base设置history后仍有#号

manifest.json文件设置&#xff1a; "h5": { "router": { "base": "./", "mode": "history" }, }按相对路径发行时路由模式强制为hash模式&#xff0c;不支持history模式&#xff08;两者相悖&#xff09;…