JVM专题九:JVM分代知识点梳理
今天开始,咱们开始剖析JVM内存划分的原理细节,以及我们创建的那些对象在JVM中到底是如何分配,如何流动的,首先解决第一个问题:JVM内存的一个分代模型:年轻代、老年代、永久通过之前的专题我们知道,那就是我们在代码里创建的对象,“都”会进入到Java堆内存。
为什么需要分代
JVM需要分代的主要原因是优化垃圾回收(Garbage Collection, GC)的效率。以下是分代垃圾回收模型的几个关键优势:
-
对象生命周期的统计特性: 大多数对象都是朝生夕死,即它们被创建后很快就会变得不再被使用。分代模型利用了这一特性,将新创建的对象放在年轻代,这样大部分短暂的对象可以快速被回收,而不需要频繁地对整个堆进行垃圾回收。
-
垃圾回收效率: 年轻代的垃圾回收(Minor GC)通常比老年代的垃圾回收(Major GC或Full GC)要快得多,因为年轻代的对象数量多,但存活率低。通过在年轻代进行频繁的垃圾回收,可以快速清理大量不再使用的对象,减少对老年代的影响。
-
减少Full GC的频率: 由于大部分对象在年轻代就会被回收,因此进入老年代的对象相对较少,这减少了对整个堆进行垃圾回收(Full GC)的需要,Full GC通常成本更高,因为它需要扫描整个堆内存。
-
内存分配的局部性优化: 年轻代的内存分配通常具有很好的局部性,因为新对象倾向于在相近的内存地址上创建。这有助于现代CPU缓存的利用,从而提高内存访问效率。
-
对象老化的自然过程: 对象在年轻代中经过多次GC后,如果仍然存活,说明它们可能是长时间存活的对象。将这些对象移动到老年代可以减少年轻代中对象的老化检查,从而提高GC效率。
-
不同的垃圾回收算法: 年轻代和老年代可以使用不同的垃圾回收算法。例如,年轻代通常使用复制算法,因为它简单且高效,而老年代可能使用标记-清除或标记-清除-整理算法,因为老年代的对象存活率更高,需要更复杂的算法来处理碎片问题。
-
内存空间的合理分配: 通过分代,JVM可以根据对象的生命周期特性合理分配内存空间。年轻代通常分配较小的内存空间,因为大多数对象都是短暂存在的,而老年代则分配较大的空间,用于存放长期存活的对象。
-
适应不同的应用场景: 不同的应用可能有不同的对象生命周期特性。通过分代,JVM可以更灵活地适应不同的应用场景,通过调整年轻代和老年代的大小,以及垃圾回收算法,来优化性能。
通过上述分代模型的优势,JVM能够更高效地管理内存,减少垃圾回收的开销,从而提高Java程序的整体性能。
新生代是如何进入老年代的?
新生代对象进入老年代的过程,通常被称为"晋升"(Promotion)。以下是对象从新生代晋升到老年代的几个关键步骤和机制:
-
对象分配: 当一个新对象在Java程序中创建时,它首先被分配到新生代的Eden区。
-
Minor GC: 新生代会定期进行Minor GC,以回收Eden区和Survivor区中不再被引用的对象。存活的对象会被复制到另一个Survivor区(S0或S1)。
-
对象年龄: 在Minor GC之后,存活的对象会有一个年龄计数器,每次在Survivor区之间复制时,对象的年龄会增加。
-
年龄阈值: 对象的年龄达到一定的阈值(默认是15,但可以通过
-XX:MaxTenuringThreshold
参数调整),对象就会被认为足够"老",应该被晋升到老年代。 -
动态年龄调整: JVM会根据Survivor区的使用情况动态调整对象晋升到老年代的年龄阈值。如果Survivor区空间不足,JVM可能会降低年龄阈值,使对象更快地晋升到老年代。
-
空间分配担保: 当一个对象在Survivor区存活多次后,JVM会检查老年代的可用空间。如果老年代有足够的空间,对象会被晋升;如果没有,JVM会尝试进行一次Full GC来清理老年代的空间,然后再尝试晋升对象。
-
晋升到老年代: 一旦对象的年龄达到阈值,或者Survivor区空间不足,对象就会被复制到老年代。在老年代,对象不需要像在新生代那样频繁移动,因为老年代的垃圾回收频率较低。
-
空间分配担保的实现: 晋升过程中,JVM会使用一种称为"空间分配担保"(Space Accounting Guarantee)的策略,确保老年代有足够的空间来接收新生代晋升的对象。如果老年代空间不足,JVM会尝试压缩老年代,或者触发Full GC。
-
TLABs: 为了进一步优化内存分配,JVM还使用线程本地分配缓冲区(Thread Local Allocation Buffers, TLABs)。每个线程有自己的TLAB,用于分配对象,这样可以减少线程之间的内存分配竞争。
通过这些机制,JVM能够根据对象的生命周期特性,有效地将对象从新生代晋升到老年代,同时保持垃圾回收的效率和性能。
什么时候触发新生代垃圾回收
新生代垃圾回收(Minor GC)的触发时机如下:
-
内存分配限制:当新生代的Eden区内存耗尽,无法满足新对象的内存分配请求时,将触发Minor GC以释放内存空间。
-
内存使用监控:JVM内部监控新生代内存使用情况,当达到预设的内存使用阈值时,可能触发Minor GC。
-
GC算法实现:根据JVM所采用的垃圾回收算法实现,可能存在特定的条件或时间间隔来触发Minor GC。
-
显式GC请求:尽管
System.gc()
方法的调用并不保证立即执行GC,但它提供了一个显式的GC请求,JVM可能会响应此请求并触发Minor GC。 -
自适应调整:JVM可能采用自适应算法根据应用程序的内存分配模式和垃圾回收效率来动态决定Minor GC的触发时机。
-
内存分配速率:如果对象的内存分配速率持续超过GC回收速率,JVM可能会触发Minor GC以避免内存溢出。
-
堆内存压力:在堆内存使用接近其最大容量时,JVM可能会增加Minor GC的频率,以防止内存耗尽。
-
JVM参数配置:特定的JVM启动参数,如
-XX:+UseAdaptiveSizePolicy
,允许JVM根据当前的内存分配和回收效率自适应地调整新生代的大小和Minor GC的触发策略。 -
外部系统因素:操作系统的内存压力或资源限制也可能间接影响JVM对Minor GC的触发决策。
-
GC日志和性能监控:通过监控GC日志和性能指标,JVM可以分析对象生命周期和内存分配模式,以优化Minor GC的触发时机。
Minor GC是JVM内存管理的关键机制之一,其触发机制的设计旨在平衡内存回收的效率和应用程序的性能需求。
什么情况会进入老年代
在JVM中,对象从新生代晋升到老年代的条件主要包括以下几点:
-
年龄阈值:对象在Survivor区存活的次数达到JVM设置的年龄阈值(
-XX:MaxTenuringThreshold
参数,默认为15),该对象将被晋升到老年代。 -
空间分配担保:如果Survivor区的空间不足以容纳经过Minor GC后存活的对象,JVM会检查老年代的可用空间。如果老年代有足够的空间,这些对象将被直接晋升到老年代。
-
动态年龄调整:JVM可能会根据当前内存分配和回收的统计信息,动态调整对象晋升到老年代的年龄阈值。
-
老年代空间充足:即使对象的年龄未达到最大年龄阈值,如果老年代有足够的空间,JVM也可能将对象提前晋升到老年代。
-
Full GC后的存活对象:在执行Full GC(老年代GC)后,新生代中所有存活的对象可能被直接晋升到老年代,以减少跨代引用的问题。
-
大对象直接分配:对于占用大量连续内存的大对象(如大型数组),JVM可能会直接将其分配到老年代,以避免在新生代中分配时产生过多的内存碎片。
-
长期存活对象:某些对象由于其生命周期较长,经过多次Minor GC后仍然存活,这些对象最终会被晋升到老年代。
-
JVM参数配置:JVM参数如
-XX:TargetSurvivorRatio
(目标Survivor区使用率)和-XX:PretenureSizeThreshold
(直接分配到老年代的对象大小阈值)可以影响对象晋升到老年代的行为。 -
内存分配策略:JVM的内存分配策略,如TLAB(Thread Local Allocation Buffer)的使用,也可能影响对象是否直接在老年代分配。
-
垃圾回收器的选择:不同的垃圾回收器可能有不同的晋升策略和内存管理机制。
对象晋升到老年代是一个动态的过程,JVM会根据当前的内存使用情况和垃圾回收效率来做出最合适的决策。
分别怎么进行垃圾回收
VM中的垃圾回收(Garbage Collection, GC)主要针对新生代和老年代采用不同的策略,以下是两种区域垃圾回收的基本方法:
新生代垃圾回收(Minor GC或Young GC)
-
复制算法:新生代通常使用复制算法(Copying)。该算法将Eden区和Survivor区(S0)中存活的对象复制到另一个Survivor区(S1)。复制完成后,Eden区和S0中的所有对象都会被清理。
-
对象年龄:每次Minor GC后,存活的对象年龄会递增。当对象的年龄达到
-XX:MaxTenuringThreshold
参数设定的阈值时,对象会被晋升到老年代。 -
清理过程:Minor GC主要涉及Eden区和Survivor区的清理,不涉及老年代。
-
内存分配:新创建的对象首先分配到Eden区,或者直接分配到TLAB(如果启用)。
-
触发条件:当Eden区被填满,或者Survivor区无法容纳从Eden区复制过来的存活对象时,会触发Minor GC。
老年代垃圾回收(Major GC或Full GC)
-
标记-清除算法:老年代的垃圾回收通常从标记所有存活的对象开始,然后清除未被标记的对象。
-
标记-清除-整理:为了防止内存碎片化,清除之后可能会进行一次整理,将存活的对象移动到堆的一端,以便于连续内存分配。
-
并发收集:老年代的垃圾回收可能采用并发收集算法,以减少GC暂停时间。
-
分代收集:老年代的GC可能与新生代的GC同时进行,这种GC被称为Full GC。
-
压缩技术:为了减少内存碎片,老年代的GC可能采用压缩技术,如G1 GC的Region重排。
-
触发条件:老年代GC可能由以下条件触发:
- 老年代空间不足。
- 显式调用
System.gc()
。 - 达到某些JVM参数设定的内存使用阈值。
-
内存分配:老年代用于存放长期存活的对象,以及从新生代晋升上来的对象。
-
性能影响:由于老年代GC涉及整个堆或大部分堆的内存,它通常比Minor GC有更长的暂停时间和更大的性能影响。
总结
- 新生代GC(Minor GC)通常更频繁,使用复制算法,回收速度快,影响较小。
- 老年代GC(Major GC或Full GC)较少见,使用标记-清除(可能伴随整理)算法,回收速度慢,可能引起较长时间的暂停。
JVM的垃圾回收策略和算法可以根据具体的垃圾回收器和JVM参数进行调整,以适应不同的应用场景和性能要求。
什么是永久代?
在JVM中,永久代(Permanent Generation,简称PermGen)是方法区的一种实现,主要用于存储类信息、常量、静态变量等数据。以下是对您提供内容的扩展和澄清:
永久代(PermGen)的角色
- 类信息存储:永久代存储了类的元数据,包括类的字段、方法、构造函数等信息。
- 常量池:存储编译期就已经确定的字面量和符号引用。
- 静态变量:存储类的静态变量。
- ClassLoader数据:存储类加载器的引用。
方法区垃圾回收的条件
方法区中的类信息并不是一直存在的,它们也可以被垃圾回收。以下是类信息可以被回收的条件:
- 实例对象的回收:类的所有实例对象已经被垃圾回收,即Java堆中不存在该类的任何实例。
- ClassLoader的回收:加载该类的ClassLoader已经被垃圾回收。
- 无引用的Class对象:堆中不存在任何对该Class对象的引用。
垃圾回收机制
- 条件触发:只有当上述三个条件同时满足时,类信息才会变成垃圾,被JVM的垃圾回收机制处理。
- 回收过程:JVM在进行垃圾回收时,会检查类是否满足回收条件,如果满足,就会在下一次的Full GC中被清除。
元空间
- 元空间(Metaspace):在Java 8中,永久代被元空间所取代。元空间使用的是本地内存(Native Memory),而不是虚拟机内存(Heap Memory),这样做的好处是可以避免永久代空间不足的问题。
永久代是JVM中用于存储类信息的重要内存区域,但它并不是永久存储的。类信息在满足特定条件后可以被垃圾回收,这是JVM内存管理的一部分,有助于释放不再使用的类信息,优化内存使用。随着Java 8的发布,元空间取代了永久代,提供了更为灵活的类信息存储方式。
今天介绍了很多很多概念相关的知识点,让大家有个大概的印象,后续会一个一个剖析。
专题汇总
JVM专题一:深入分析Java工作机制
JVM专题二:Java如何进行编译的
JVM专题三:Java代码如何运行
JVM专题四:JVM的类加载机制
JVM专题五:类加载器与双亲委派机制
JVM专题六:JVM的内存模型
JVM专题七:JVM垃圾回收机制
JVM专题八:JVM如何判断可回收对象
JVM专题九:JVM分代知识点梳理
JVM专题十:JVM中的垃圾回收机制
JVM专题十一:JVM 中的收集器一
JVM专题十二:JVM 中的收集器二
JVM专题十三:总结与整理(面试常用)
相关文章:
JVM专题九:JVM分代知识点梳理
今天开始,咱们开始剖析JVM内存划分的原理细节,以及我们创建的那些对象在JVM中到底是如何分配,如何流动的,首先解决第一个问题:JVM内存的一个分代模型:年轻代、老年代、永久通过之前的专题我们知道,那就是我…...

wireshark常用过滤命令
wireshark常用过滤命令 wireshark抓包介绍单机单点:单机多点:双机并行: wireshark界面认识默认布局调整布局(常用)显示FCS错误 wireshark常见列Time回包数据报对应网络模型 wireshark基本操作结束抓包再次开始抓包 **wireshark常用过滤命令**…...

「全新升级,性能更强大——ONLYOFFICE 桌面编辑器 8.1 深度评测」
文章目录 一、背景二、界面设计与用户体验三、主要新功能亮点3.1 高效协作处理3.2 共同编辑,毫无压力3.3 批注与提及3.4 追踪更改3.5 比较与合并3.6 管理版本历史 四、性能表现4.1 集成 AI 工具4.2 插件强化 五、用户反馈与使用案例 一、背景 Ascensio System SIA -…...

线程版服务器实现(pthread_server)
用到的所有方法所需要的参数可以在wrap.c文件中查询,wrap中找不到的直接通过man手册查询 1.首先介绍一下我自己写的包裹文件,里面有各种在可能要用到的方法 wrap.c: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #…...

js异常处理方案
文章目录 异常处理方案同步代码的异常处理Promise 的异常处理async await 的异常处理 感谢阅读,觉得有帮助可以点点关注点点赞,谢谢! 异常处理方案 在JS开发中,处理异常包括两步:先抛出异常,然后捕获异常。…...
C++文件路径处理2 - 路径拼接路径解析
1. 关键词2. filesystem.h3. filepath.cpp6. 测试代码7. 运行结果8. 源码地址 1. 关键词 关键词: C 文件路径处理 路径拼接 获取父目录的路径 获取文件名 获取拓展名 跨平台 应用场景: 路径的拼接路径的解析 2. filesystem.h #pragma once#include…...

数据结构5---矩阵和广义表
一、矩阵的压缩存储 特殊矩阵:矩阵中很多值相同的元素并且它们的分布有一定的规律。 稀疏矩阵:矩阵中有很多零元素。压缩存储的基本思想是: (1)为多个值相同的元素只分配一个存储空间; (2)对零元素不分配存储空间。 1、特殊矩阵的压缩存储 (1)对称矩…...
jquery使用infinitescroll无线滚动+自定义翻页
jquery版本 jquery-1.8.3.js infinitescroll版本 2.0.0 如果infinitescroll版本最新的jquery版本也要用新的 接口用nodejs jquery.infinitescroll.js官网地址 前端代码《接口返回JSON数据》 <!DOCTYPE html> <html lang"en"> <head><meta cha…...

【漏洞复现】锐捷统一上网行为管理与审计系统——远程命令执行漏洞
声明:本文档或演示材料仅供教育和教学目的使用,任何个人或组织使用本文档中的信息进行非法活动,均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 锐捷统一上网行为管理与审计系统naborTable/static_convert.php…...

通义灵码上线 Visual Studio 插件市场啦!
通义灵码,是阿里云出品的一款基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、代码解释、研发智能问答、异常报错排查等能力,提供代码智能生成、研发智能问答能力。 通义灵…...
GESP 四级急救包(2):客观题真题集
客观题真题集 一、选择题1. 真题梳理2. 真题答案3. 重难点点播(1) 指针和地址(2) 时间复杂度 二、判断题1. 真题梳理2. 真题答案 一、选择题 1. 真题梳理 若函数声明为 void f(int &a, int b, const int &c),且在主函数内已经声明了 x , y , z x,y,z x,y,…...

VERYCLOUD睿鸿股份确认参展2024年ChinaJoy BTOB商务洽谈馆,期待与你相聚
作为在全球数字娱乐领域兼具知名度与影响力的年度盛会,2024年第二十一届ChinaJoy将于7月26日至7月29日在上海新国际博览中心盛大召开,本届展会主题为:初心“游”在,精彩无限!(Stay True, Game On.ÿ…...
Java面试题:讨论Spring框架的核心组件,如IoC容器、AOP、事务管理等
Spring框架是一个功能强大且灵活的Java企业级应用开发框架,其核心组件包括以下几个主要部分: 1. IoC容器(Inversion of Control Container) IoC容器是Spring框架的核心部分,用于管理应用程序的依赖注入(D…...

【方案】基于5G智慧工业园区解决方案(PPT原件)
5G智慧工业园区整体解决方案旨在通过集成5G通信技术、物联网、大数据和云计算等先进技术,实现园区的智能化、高效化和绿色化。 该方案首先构建高速、稳定的5G网络,确保园区内设备、人员与物流的实时连接和高效沟通。其次,通过工业物联网技术&…...
使用System.currentTimeMillis获取当前时间
使用System.currentTimeMillis获取当前时间 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来探讨Java中如何使用System.currentTimeMillis()方法来获取…...

手机远程控制另一台手机的全新使用教程(安卓版)
看完这篇文章,你可以了解到安卓手机如何远程控制安卓手机,以及苹果手机如何远程控制安卓手机。 如果想要用安卓手机远程管控苹果手机,或者苹果手机远程管控另一台苹果手机,请点击查看视频《手机远程管控另一台手机的全新使用教程…...

商城积分系统的代码实现(上)-- 积分账户及收支记录
一、背景 上一系列文章,我们说了积分的数模设计及接口设计,接下里,我们将梳理一下具体的代码实现。 使用的语言的java,基本框架是spring-boot,持久化框架则是Jpa。 使用到的技术点有: 分布式锁…...

【C++进阶9】异常
一、C语言传统的处理错误的方式 终止程序,如assert 如发生内存错误,除0错误时就会终止程序返回错误码 需要程序员自己去查找对应的错误 z如系统的很多库的接口函数都是通 过把错误码放到errno中,表示错误 二、C异常概念 异常:函…...

RecyclerVIew->加速再减速的RecyclerVIew平滑对齐工具类SnapHelper
XML文件 ItemView的XML文件R.layout.shape_item_view <?xml version"1.0" encoding"utf-8"?> <FrameLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"100dp"android:layout_heig…...

突破SaaS产品运营困境:多渠道运营如何集中管理?
随着数字化时代的到来,SaaS(软件即服务)产品已成为企业日常运营不可或缺的工具。然而,在竞争激烈的市场环境下,SaaS产品运营越来越重视多渠道、多平台布局,以更广泛地触及潜在用户,然而…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...