JVM-JVM中对象的生命周期

申明:文章内容是本人学习极客时间课程所写,文字和图片基本来源于课程资料,在某些地方会插入一点自己的理解,未用于商业用途,侵删。
原资料地址:课程资料

对象的创建

在这里插入图片描述

常量池检查:检查new指令是否能在常量池中定位到这个类的符号引用,检查类之前是否被加载过。如果已经加载则直接使用,否则需要进行加载。
分配内存空间
有两种方式:

  • 指针碰撞 由Serial 和 ParNew去回收
  • 空闲列表 有CMS和Mark-Sweep回收
    必要信息的设置:对象的元数据,对象哈希码,GC分代年龄 -> 对象头
    在这里插入图片描述
    指针碰撞往往是一片连续的区域,空闲列表是非连续的。
    在这里插入图片描述
    内存分配存在的问题
    1 线程安全问题,因为堆是共享的,如果多个线程同时执行可能存在线程安全问题。
    解决方案:
    1) 通过CAS乐观锁:IVM虚拟机采用CAS失败重试的方式保证更新操作的原子性
    2)TLAB (Thread LocalAllocation Buffer) 本地线程分配缓存,预分配(也就是先给这个线程分配一个私有的内存,这样就不会有并发问题)
    分配主流程:首先从TLAB里面分配,如果分配不到,再使用CAS从堆里面划分

分配内存分配是是老年代还是年轻代
内存的分配大多数new出来的对象都是新生代,但是也有部分会去到老年代(比如大对象,在新生代无法放下)。
必要信息设置
对象类的元数据,对象哈希码,GC分带年龄(存储在对象头中)

对象进入老年代

在这里插入图片描述
进入老年代的条件
1 存活年龄太大,默认超过15次【-XX:MaxTenuringThreshold】(GC过程中会讲)
在这里插入图片描述
1 在MinorGC的时候存活的对象会被复制到幸存区域年龄 + 1 2 下一次GC的时候幸存取的对象和Eden的对象存活的对象会被复制到第二块幸存区域 年龄 + 1 3 这样来回复制如果对象的年龄大于15就会放入老年代,可以修改这个值
2 动态年龄判断:MinorGC之后,发现Survivor区中的一批对象的总大小大于了这块Survivor区的50%,那么就会将此时大于等于这批对象年龄最大值的所有对象,直接进入老年代。
-XX:TargetSurvivorRatio可以指定
举个栗子:Survivor区中有一批对象,年龄分别为年龄1+年龄2+年龄n的多个对象,对象总和大小超过了Survivor区域的50%,此时就会把年龄n及以上的对象都放入老年代。
为什么会这样?
希望那些可能是长期存活的对象,尽早进入老年代。

3 大对象直接进入老年代:前提是Serial和ParNew收集器
大对象可以通过这个参数去配置: -XX:PretenureSizeThreshold 一般设置为1M
举个栗子:字符串或数组
为什么会这样?为了避免大对象分配内存时的复制操作降低效率。避免了Eden和Survivor区的复制

空间担保机制:当新生代无法分配内存的时候,我们想把新生代的老对象转移到老年代,然后把新对象放入腾空的新生代。此种机制我们称之为内存担保。
4 MinorGC后,存活对象太多无法放入Survivor

  • MinorGC前,判断老年代可用内存是否小于新时代对象全部对象大小,如果小于则继续判断老年代可用内存大小是否小于之前每次MinorGC后进入老年代的对象平均大小
    如果是,则会进行一次FullGC,判断是否放得下,放不下OOM
    如果否(代表老年代能放下),则会进行MinorGC:
    MinorGC后,剩余存活对象小于Survivor区大小,直接进入Survivor区
    MinorGC后,剩余存活对象大于Survivor区大小,但是小于老年代可用内存,直接进入老年代
    MinorGC后,剩余存活对象大于Survivor区大小,也大于老年代可用内存,进行FullGC
    FullGC之后,任然没有足够内存存放MinorGC的剩余对象,就会OOM
    在这里插入图片描述

案例1,大对象直接进入老年区:

// -Xmx60m -Xms60m -XX:NewRatio=2 -XX:SurvivorRatio=8 -XX:+PrintGCDetails
// Xmx 程序运行时最大内存大小
// Xms 程序启动时最大内存大小
// NewRatio 年轻代和老年代的比例为1:2
// SurvivorRatio survivor区域和eden 区域的内存比例 1 : 8
// PrintGCDetails 打印详细日志
public static void main(String[] args) {byte[] buffer = new byte[1024*1024*20];}

在这里插入图片描述
在这里插入图片描述
由这个例子我们可以得出结论因为年轻代的内存总共也就18M左右导致年轻代无法存放我们创建的20M大小的数组,所以直接放入到了老年代。
案例2:

// -Xmx600m -Xms600m -XX:+PrintGCDetails
public class HeapInstance {public static void main(String[] args) {List<Picture> list = new ArrayList<>();while (true) {try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}list.add(new Picture(new Random().nextInt(1024 * 1024)));}}
}public class Picture {private byte[] pixels;public Picture(int length){this.pixels = new byte[length];}
}

与前面的描述呼应,进行三次FG后任然无法分配内存,则OOM。整个过程大致是这样,我们不断地创建对象,然后Eden区逐渐被占满,从而一部分对象复制到幸存区,然后幸存区(这个过程中会有动态年龄的判断来回复制)放不下了进入老年区,直到老年区也无法放下就内存溢出。
在这里插入图片描述

案例3,动态内存担保机制的演示:
空间担保机制:当新生代无法分配内存的时候,我们想把新生代的老对象转移到老年代,然后把新对象放入腾空的新生代。此种机制我们称之为内存担保。

// -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:+UseSerialGC
// 初始内存  最大内存  年轻第空间  
public class Demo {private static final int _1MB = 1024 * 1024;public static void main(String[] args) {memoryAllocation();}public static void memoryAllocation() {byte[] allocation1, allocation2, allocation3, allocation4;allocation1 = new byte[1 * _1MB];//1Mallocation2 = new byte[1 * _1MB];//1Mallocation3 = new byte[1 * _1MB];//1Mallocation4 = new byte[5 * _1MB];//5MSystem.out.println("完毕");}
}

JVM参数
在这里插入图片描述
可以看到老年代存了一个大约3M的对象,年轻代存大约6M的一个对象。
那么它执行的流程是这样的,前面3M的对象在eden区域分配后,后面来了一个5M的对象,发现内存不足,于是将之前3M 的数据移入了老年代,之后将5M的数据放入新生代,这就是内存担保机制。

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

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

相关文章

openEuler 22.03 LTS 上源码安装 PostgreSQL 15

安装PostgreSQL 15 1 安装必要的依赖 #yum install -y readline-devel zlib-devel gcc2、下载源码 # wget https://ftp.postgresql.org/pub/source/v15.6/postgresql-15.6.tar.gz # tar -xzvf postgresql-15.6.tar.gz3 配置 # cd postgresql-15.6/ # ./configure4 编译安装…

Matlab|基于支持向量机的电力短期负荷预测【三种方法】

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序主要是对电力短期负荷进行预测&#xff0c;采用三种方法&#xff0c;分别是最小二乘支持向量机&#xff08;LSSVM&#xff09;、标准粒子群算法支持向量机和改进粒子群算法支持向量机三种方法对负荷进行…

Nginx反向代理多虚拟主机节点服务器

IP规划: servera,serverd作为web服务器 serverb作为nginx负载均衡服务器 serverc域名映射服务器 servera(192.168.233.132)配置: # 安装Nginx yum install nginx -y# 进入Nginx配置文件目录 cd /etc/nginx/conf.d/# 编辑配置文件&#xf…

讲解用Python处理Excel表格

我们今天来一起探索一下用Python怎么操作Excel文件。与word文件的操作库python-docx类似&#xff0c;Python也有专门的库为Excel文件的操作提供支持&#xff0c;这些库包括xlrd、xlwt、xlutils、openpyxl、xlsxwriter几种&#xff0c;其中我最喜欢用的是openpyxl&#xff0c;这…

【天幕系列 02】开源力量:揭示开源软件如何成为技术演进与社会发展的引擎

文章目录 导言01 开源软件如何推动技术创新1.1 开放的创新模式1.2 快速迭代和反馈循环1.3 共享知识和资源1.4 生态系统的建设和扩展1.5 开放标准和互操作性 02 开源软件的商业模式2.1 支持和服务模式2.2 基于订阅的模式2.3 专有附加组件模式2.4 开源软件作为平台模式2.5 双重许…

【计算机网络】物理层|传输介质|物理层设备|宽带接入技术

目录 一、思维导图 二、传输介质 1.传输介质——导引型 2.传输介质——非导引型​编辑 三、物理层设备 1.物理层设备&#xff1a;中继器&集线器 2.宽带接入技术&#xff08;有线&#xff09; ​编辑 四、趁热打铁☞习题训练 五、物理层总思维导图 推荐 前些天发现…

【C++】友元、内部类和匿名对象

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 1. 友元 1.1 友元函数 1.2 友元类 2. 内部类 2.1 成员内部类 2.2 局部内部类 3. 匿名对象 3.1 基本概念 3.1 隐式转换 1…

Node.js开发-MongoDB

MongoDB 1) Mongoose2) 插入文档3) 字段类型4) 字段值验证5) CRUD1) 增加2) 删除3) 更新4) 查询 6) 条件控制1) 运算符2) 逻辑运算3) 正则匹配 7) 个性化读取1) 字段筛选2) 数据排序3) 数据截取 1) Mongoose 介绍 Mongoose 是一个对象文档模型库&#xff0c;官网 http://www.…

在已有代码基础上创建Git仓库

在已有代码基础上创建Git仓库 背景方法处理问题 背景 先进行了代码编写&#xff0c;后续想放入仓库方便大家一起合作开发&#xff0c;此时需要在已有代码的基础上建立仓库。 方法 首先在Gitee或者GitHub上创建仓库&#xff0c;这里以Gitee为例。创建完后&#xff0c;我们可以…

各类有关于花卉的深度学习数据集

花卉的识别和分类在深度学习过程中是最常见的使用的案例&#xff0c;因此各类有关花卉分类、识别、计数的图像数据集是大家都常用的数据集。最近收集到各类有关花卉的各类数据集分享给大家&#xff01;&#xff01; 1、16种花常见的图像数据集 数据说明&#xff1a;我们看到我…

Blazor SSR/WASM IDS/OIDC 单点登录授权实例1-建立和配置IDS身份验证服务

目录: OpenID 与 OAuth2 基础知识Blazor wasm Google 登录Blazor wasm Gitee 码云登录Blazor SSR/WASM IDS/OIDC 单点登录授权实例1-建立和配置IDS身份验证服务Blazor SSR/WASM IDS/OIDC 单点登录授权实例2-登录信息组件wasmBlazor SSR/WASM IDS/OIDC 单点登录授权实例3-服务端…

1070A A. Find a Number bfs同时处理数和数位和 ,依次处理每一位数

Problem - 1070A - Codeforces A - Find a Number CodeForces - 1070A -记忆化广搜-同余定理_codeforces 1070a find a number(bfs)-CSDN博客 这个大佬的博客代码写的非常好看。 ———— &#xff08;其实第二个样例32位的数long long存不下&#xff0c;就知道这道题不是寻…

【实战】一、Jest 前端自动化测试框架基础入门(二) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(二)

文章目录 一、Jest 前端自动化测试框架基础入门5.Jest 中的匹配器toBe 匹配器toEqual匹配器toBeNull匹配器toBeUndefined匹配器和toBeDefined匹配器toBeTruthy匹配器toBeFalsy匹配器数字相关的匹配器字符串相关的匹配器数组相关的匹配器异常情况的匹配器 6.Jest 命令行工具的使…

DSA 经典数据结构与算法 学习心得和知识总结(三) |有向无环图及其应用

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《算法导论》第三版 就是这本被封神的杰作&#xff0c;就是它&#x1f926; 2、参考书籍&#xff1a;《数据结构》严奶奶版 3、参考书…

DataX源码分析-插件机制

系列文章目录 一、DataX详解和架构介绍 二、DataX源码分析 JobContainer 三、DataX源码分析 TaskGroupContainer 四、DataX源码分析 TaskExecutor 五、DataX源码分析 reader 六、DataX源码分析 writer 七、DataX源码分析 Channel 八、DataX源码分析-插件机制 文章目录 系列文章…

基于GPT一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

Prompt Tuning:深度解读一种新的微调范式

阅读该博客&#xff0c;您将系统地掌握如下知识点&#xff1a; 什么是预训练语言模型&#xff1f; 什么是prompt&#xff1f;为什么要引入prompt&#xff1f;相比传统fine-tuning有什么优势&#xff1f; 自20年底开始&#xff0c;prompt的发展历程&#xff0c;哪些经典的代表…

【ASP.NET Core 基础知识】--最佳实践和进阶主题--微服务和容器化

Tip&#xff1a;想要了解并学习微服务和容器化的知识&#xff0c;请跳转到《Docker极简教程》 一、微服务概述 1.1 什么是微服务&#xff1f; 微服务&#xff08;Microservices&#xff09;是一种软件架构风格&#xff0c;其中软件系统被划分为一组小型、自治的服务单元&…

CV | Segment Anything论文详解及代码实现

本文主要是详解解释了SAM的论文部分以及代码实现~ 论文&#xff1a;2023.04.05_Segment Anything 论文地址&#xff1a;2304.02643.pdf (arxiv.org) 代码地址&#xff1a;facebookresearch/segment-anything: The repository provides code for running inference with the Seg…

RabbitMQ实现延迟消息的方式-死信队列、延迟队列和惰性队列

当一条消息因为一些原因无法被成功消费&#xff0c;那么这这条消息就叫做死信&#xff0c;如果包含死信的队列配置了dead-letter-exchange属性指定了一个交换机&#xff0c;队列中的死信都会投递到这个交换机内&#xff0c;这个交换机就叫死信交换机&#xff0c;死信交换机再绑…