JVM学习(二)

news2024/11/27 16:36:18
1. JVM 运行时内存
        Java 堆从 GC 的角度还可以细分为: 新生代 ( Eden 区 From Survivor 区 To Survivor 区 )和 老年 代。
1.1. 新生代
        是用来存放新生的对象。一般占据堆的 1/3 空间。由于频繁创建对象,所以新生代会频繁触发 MinorGC 进行垃圾回收。新生代又分为 Eden 区、ServivorFrom、ServivorTo 三个区。
1.1.1. Eden
        Java 新对象的出生地 (如果新创建的对象占用内存很大,则直接分配到老 年代)。当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行 一次垃圾回收。
1.1.2.        ServivorFrom
        上一次 GC 的幸存者,作为这一次 GC 的被扫描者。
1.1.3. ServivorTo
        保留了一次 MinorGC 过程中的幸存者。
1.1.4. MinorGC 的过程(复制->清空->互换)
        MinorGC 采用 复制算法
        1: eden servicorFrom 复制到 ServicorTo,年龄+1
        首先,把 Eden 和 ServivorFrom 区域中存活的对象复制到 ServicorTo 区域(如果有对象的年
龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果 ServicorTo 不
够位置了就放到老年区);
        2:清空 eden servicorFrom
        然后,清空 Eden 和 ServicorFrom 中的对象;
        3: ServicorTo ServicorFrom 互换
        最后,ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom
区。
1.2. 老年代
        主要存放应用程序中生命周期长的内存对象。
        老年代的对象比较稳定,所以 MajorGC 不会频繁执行。在进行 MajorGC 前一般都先进行
了一次 MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。当无法找到足
够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间。
MajorGC 采用 标记清除算法 :首先扫描一次所有老年代,标记出存活的对象,然后回收没 有标记的对象。MajorGC 的耗时比较长,因为要扫描再回收。MajorGC 会产生内存碎片,为了减 少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。当老年代也满了装不下的 时候,就会抛出 OOM(Out of Memory)异常。
1.3. 永久代
        指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息,Class 在被加载的时候被
放入永久区域,它和和存放实例的区域不同, GC 不会在主程序运行期对永久区域进行清理 。所以这
也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。
1.3.1. JAVA8 与元数据
        在 Java8 中, 永久代已经被移除,被一个称为“元数据区”(元空间)的区域所取代 。元空间
的本质和永久代类似,元空间与永久代之间最大的区别在于: 元空间并不在虚拟机中,而是使用
本地内存 。因此,默认情况下,元空间的大小仅受本地内存限制。 类的元数据放入 native
memory, 字符串池和类的静态变量放入 java 堆中 ,这样可以加载多少类的元数据就不再由
MaxPermSize 控制, 而由系统的实际可用空间来控制。
1.4. 垃圾回收与算法

 

 

1.4.1. 如何确定垃圾
1.4.1.1. 引用计数法
        在 Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个 对象如果没有任何与之关 联的引用,即他们的引用计数都不为 0,则说明对象不太可能再被用到,那么这个对象就是可回收 对象
1.4.1.2. 可达性分析
        为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots” 对象作为起点搜索。如 果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的 要注意的是,不可达对象不等价于可回收对象, 不可达对象变为可回收对象至少要经过两次标记 过程。两次标记后仍然是可回收对象,则将面临回收。
1.4.2. 标记清除算法( Mark-Sweep
        最基础的垃圾回收算法,分为 两个阶段,标注和清除 。标记阶段标记出所有需要回收的对象,清 除阶段回收被标记的对象所占用的空间。如图

 

从图中我们就可以发现,该算法 最大的问题是内存碎片化严重 ,后续可能发生大对象不能找到可
利用空间的问题。
1.4.3. 复制算法( copying
        为了解决 Mark-Sweep 算法内存碎片化的缺陷而被提出的算法。按内存容量将内存划分为等大小 的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用 的内存清掉,如图:

 

这种算法虽然实现简单,内存效率高,不易产生碎片,但是最大的问题是可用内存被压缩到了原
本的一半。且存活对象增多的话,Copying 算法的效率会大大降低。
1.4.4. 标记整理算法 (Mark-Compact)
        结合了以上两个算法,为了避免缺陷而提出。标记阶段和 Mark-Sweep 算法相同, 标记后不是清 理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象 。如图:

 

1.4.5. 分代收集算法
        分代收集法是目前大部分 JVM 所采用的方法,其核心思想是根据对象存活的不同生命周期将内存 划分为不同的域,一般情况下将 GC 堆划分为老生代(Tenured/Old Generation)和新生代(Young Generation)。老生代的特点是每次垃圾回收时只有少量对象需要被回收,新生代的特点是每次垃 圾回收时都有大量垃圾需要被回收,因此可以根据不同区域选择不同的算法。
1.4.5.1. 新生代与复制算法
        目前大部分 JVM 的 GC 对于新生代都采取 Copying 算法,因为新生代中每次垃圾回收都要
回收大部分对象,即要复制的操作比较少,但通常并不是按照 1:1 来划分新生代。一般将新生代
划分为一块较大的 Eden 空间和两个较小的 Survivor 空间(From Space, To Space),每次使用
Eden 空间和其中的一块 Survivor 空间,当进行回收时,将该两块空间中还存活的对象复制到另
一块 Survivor 空间中。
1.4.5.2. 老年代与标记复制算法
        而老年代因为每次只回收少量对象,因而采用 Mark-Compact 算法。
1. JAVA 虚拟机提到过的处于 方法区的永生代(Permanet Generation),它用来存储 class 类,
常量,方法描述等 。对永生代的回收主要包括废弃常量和无用的类。
2. 对象的内存分配主要在新生代的 Eden Space 和 Survivor Space 的 From Space(Survivor 目
前存放对象的那一块),少数情况会直接分配到老生代。
3. 当新生代的 Eden Space 和 From Space 空间不足时就会发生一次 GC,进行 GC 后,Eden
Space 和 From Space 区的存活对象会被挪到 To Space,然后将 Eden Space 和 From
Space 进行清理。
4. 如果 To Space 无法足够存储某个对象,则将这个对象存储到老生代。
5. 在进行 GC 后,使用的便是 Eden Space 和 To Space 了,如此反复循环。
6. 当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。 默认情况下年龄到达 15 的对象会被
移到老生代中。

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

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

相关文章

《如何评价北化面向对象江某英之我是传奇》

点进来的都是家人了,来,今天带你们一起速通江某英的面向对象。 首先,我们先看一下江某英的教学安排,所谓知己知彼,百战不殆。 一共是九个章节,但是最后一个总复习没讲,这不是为难我们吗&#x…

【移动端网页布局】Flex 弹性布局案例 ② ( 顶部固定定位搜索栏 | 固定定位盒子居中对齐 | 二倍精灵图设置 | CSS3 中的垂直居中对齐 )

文章目录 一、顶部固定定位搜索栏1、固定定位盒子居中对齐2、设置最大宽度和最小宽度3、使用 Flex 弹性布局管理宽度4、二倍精灵图设置5、CSS3 中的垂直居中对齐 - 行高 内容高度 ( 总高度 - 边框高度 - 内边距高度 ) 二、代码示例1、HTML 标签结构2、CSS 样式3、展示效果 一、…

Pytroch nn.Unfold() 与 nn.Fold()图码详解

文章目录 Unfold()与Fold()的用途nn.Unfold()Unfold()与Fold() 变化模式图解 nn.Fold()单通道 滑动窗口无重叠模拟图片数据(b,3,9,9),通道数 C 为3,滑动窗口无重叠。单通道 滑动窗口有重叠。 卷积等价于:Unfold Matri…

国民技术N32G430开发笔记(20)- FreeRTOS的移植

FreeRTOS的移植 1、官网下载FreeRTOSv202212.01,搜索官网下载即可。 2、新建一个FreeRTOSDemo的工程,可以把之前的工程中的Bootloader工程复制一份。 3、打开下载的freertos代码将相应代码移植到我们的工程中。 protable文件夹,因为是gcc环…

ChatGPT国内镜像网站集合

ChatGPT是一个基于人工智能的聊天机器人,它可以与用户进行自然语言交互。ChatGPT使用了最新的自然语言处理技术,包括深度学习和神经网络,以便更好地理解用户的意图和回答用户的问题。 ChatGPT可以回答各种问题,包括但不限于常见问…

RabbitMQ如何避免丢失消息

目录标题 消息丢失1. 生产者生产消息到RabbitMQ Server 消息丢失场景1. 网络问题2. 代码层面,配置层面,考虑不全导致消息丢失解决方案:开启confirm模式 2. 队列本身可能丢失消息1. 消息未完全持久化,当机器重启后,消息…

shell脚本之“sed“命令

文章目录 1.sed编辑器概述2.sed命令常用选项3.sed命令常用操作4.sed命令演示操作部分5.总结 1.sed编辑器概述 sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据,这些…

C嘎嘎~~[类 下篇 之 日期类的实现]

类 下篇 之 日期类的实现 6.const成员6.1 const成员的引入6.2const成员的概念 7.日期类的实现 6.const成员 6.1 const成员的引入 class Date { public:// 构造函数Date(int year 2023, int month 5, int day 5){_year year;_month month;_day day;}void Print(){cout &…

【STL】vector的使用

目录 前言 默认成员函数 构造函数 拷贝构造 赋值重载 迭代器 正向迭代器 反向迭代器 容量管理 查看容量和大小 扩容 判空 访问数据 下标访问 边界访问 数据修改 尾插尾删 指定位置插入删除 迭代器失效 清空 ​编辑 交换 查找数据 vector可以代替strin…

VOACAP 软件的简单介绍

VOACAP 软件可以预测短波通信中的最高可用频率、最佳传输频率、角度、延迟、反射点高度、信噪比、收发增益等参数,它可以直接输出文本文件,或者以图表输出,同时,它也可以绘制某一参数随时间、距离的变化图表。 该软件的下载安装可…

C语言从入门到精通第18天(指针和函数的联用)

指针和函数的联用 一级指针作为函数的形参二级指针 一级指针作为函数的形参 当函数的形参为数组时,我们定义函数如下: 语法: 数据类型 函数名(数据类型 数组名) 例如 : void func(int a[],int a){ 语句; } 但是在实际使用中我们通常用指针的形式进行…

GEE:如何进行对MOD09GA数据集进行水体/云掩膜并计算NDVI将其导出至云盘?

目录 01 为什么用GEE而不是传统的下载ENVIArcGIS? 02 操作详解 01 为什么用GEE而不是传统的下载ENVIArcGIS? 由于地理空间数据云中缺少2015年10月份的NDVI月合成影像,于是查看了地理空间数据云的NDVI数据集处理的一些介绍如下(地理空间数据…

【Linux内核】信号量semaphore机制

信号量实现方法 信号量机制是一种用于控制并发访问的同步机制,常用于多进程或多线程之间的协调。在Linux内核中,信号量机制是通过struct semaphore结构体来实现的。 每个semaphore结构体包含一个计数器和一个等待队列,它们用于跟踪当前可用…

Linux 并发与竞争

一、并发与竞争 1、并发 Linux 系统是个多任务操作系统,会存在多个任务同时访问同一片内存区域,这些任务可 能会相互覆盖这段内存中的数据,造成内存数据混乱。 多线程并发访问, Linux 是多任务(线程)的系统,所以多线…

命令firewalld和firewall-cmd用法

firewalld命令跟firewall-cmd 1.启动firewalld服务 systemctl start firewalld.service2.关闭firewalld服务 systemctl stop firewalld.service3.重启firewalld服务 systemctl restart firewalld.service4.查看firewalld状态 systemctl status firewalld.service5.开机自启…

接口测试怎么做?全网最详细从接口测试到接口自动化详解,看这篇就够了...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 抛出一个问题&…

孙鑫VC++第三章 2.基于MFC的程序框架剖析

目录 1. MFC向导生成类 2. 框架流程 2.1 WinMain 2.2 全局对象:theApp 2.3 AfxWinMain函数 1.AfxWinMain: 2.AfxGetThread函数(thrdcore.cpp): 3.AfxGetApp是一个全局函数,定义于(afxwin1…

原型/原型链/构造函数/类

认识构造函数 为什么有构造函数 因为一般的创建对象的方式一次只能创建一个对象, 利用工厂模式创建的对象,对象的类型都是Object类型 什么是构造函数 构造函数也称之为构造器(constructor),通常是我们在创建对象时会调用的函数…

Uni-app项目应用总结(一)

目录 一.新建uniapp项目 第一步:下载HBuilder 第二步:创建uni-app项目 第三步:运行uni-app 二.uni-app组件使用 三.uni-app路由跳转  1.页面路由配置    (1)在pages.json中配置页面路由    (2)在pages.json中配置底部导航栏 2.路由跳转方法…

【输配电路 DZY-104端子排中间继电器 接通、信号转换 JOSEF约瑟】

DZY-104端子排中间继电器品牌:JOSEF约瑟型号:DZY-104名称:端子排式中间继电器触点容量:5A/250V功率消耗:≤1.5W/≤3W/≤7W/≤3VA/≤7VA/≥5W绝缘电阻:≥10MΩ 系列型号: DZY-101端子排中间继电器; DZY-104端子排中间继电器; DZY-105端子排…