论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
云原生
›
【Java 8】JVM内存架构和GC算法根本分析
【Java 8】JVM内存架构和GC算法根本分析
耶耶耶耶耶
金牌会员
|
2024-9-19 07:55:14
|
显示全部楼层
|
阅读模式
楼主
主题
986
|
帖子
986
|
积分
2958
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
1. 目标
本文讨论了
JDK8
及以上版本的内存管理的根本概念,包罗堆和堆栈内存,以及 GC 及其算法的根本知识。
2. 内存管理的重要性
Java 垃圾收集器不能确保堆内存完全开释,而且对于开辟人员来说,无法欺压垃圾收集器在特定时间运行。因此,了解 Java 中的内存管理如何工作很有帮助。
了解内存管理有助于编写优化的内存高效代码,并有助于制止程序中任何与内存相关的题目,这些题目可能会导致应用程序运行缓慢,并有助于制止诸如StackOverFlowError 和之类的错误OutOfMemoryError。
3. 堆栈内存
堆栈
是一种线性数据结构,是 Java 分配的
静态内存
,用于存储堆对象引用,还存储 Java 原始范例值。堆栈以后进先出 (LIFO)
顺序访问内存,堆栈比堆
内存
更快
。
每个线程在内存中创建自己的堆栈,这反过来又使得堆栈内存线程安全。
Java 中的方法仅访问方法体内(方法作用域内)堆栈内存中的对象。当方法执行完成后,该方法对应的块将从堆栈中清除。
在上面的程序中,我们可以看到,当控件到达方法时main,堆栈中会有一个条目args。然后当控件位于下一行时,堆栈中会添加一个新条目。
当控制超出方法的范围时,引用将从堆栈中删除。
如果堆栈内存已满,JVM 将抛出StackOverFlowError
。
4. 堆内存
堆用于 JVM 在运行时为 Java 对象分配动态内存。任何新对象都存储在堆中,而reference(example variables)
对象的变量存储在堆栈中。您可以在下面的示例中看到示例代码中的变量如何存储在堆和堆栈中。
int age = 5;
String name = "Sherine";
List<String> subjectLst = new ArrayList<String>();
subjectLst.add("English");
subjectLst.add("Science");
List<String> finalLst;
finalLst = subjectLst;
复制代码
下面是上述代码片段的堆中的内存分配。
堆内存可以分解为多个较小的部分,称为
代,
即年轻代、老生代/终身代
和
永久代
。
4.1 年轻代
所有新对象都分配在此内存段中。年轻代由
Eden
和
两个
Survivor 空间
构成。当 Eden 填满时,垃圾收集发生在年轻代,这称为
Minor GC
。
在 Minor GC 期间,年轻代中引用的对象将移动到 Survivor 空间 #1,而且对象的年龄会增长。
比方,在下图中,“对象 1”和“对象 2”将在第一次 Minor GC 后移至 Survivor 空间 #1,而且它们将具有指定的年龄。如果“对象 1”在第一次 Minor GC 后幸存下来,则年龄为零。如今,如果“对象 1”在下一次 Minor GC 后也幸存下来,则它将被移至 Survivor 空间 2,而且年龄将再次增长。
图 1:Eden 已满,在 Minor GC 之前
在第二次 Minor GC 期间,位于 Survivor 空间 #1 中的对象(具有引用)将被移动到 Survivor #2,而且年龄将增长(即,年龄将按照示例从零变为一)。而且,所有未引用的来自已满的年轻代空间的对象都将被删除。
图 2:第一次 Minor GC 之后
年轻代的巨细可以通过 来控制NewRatio。如果我们设置,则意味着年轻代和老代/终身代的比例将是 1:4,而 Eden 和 Survivor 空间的总空间将是总堆巨细的 1/5。您还可以利用JVM 选项设置-XX:NewRatio=4年轻代的巨细 。NewSizeMaxNewSize
4.2 老年代
老年代是存储长寿对象(大多数老龄对象)的地方。年轻代对象有年龄上限或阈值。一旦对象到达该上限,就会将其移至老年代或终身代。
4.3 长期代
这部分堆内存用于存储运行时类和方法的元数据。Java从
JDK 8
开始已完全删除这部分内存,并
用 Metaspace
概念取代。您仍然可以设置--XX
ermSize和-XX:MaxPermSize设置。但是,如果您在 JDK 8 或更高版本上运行应用程序,则会在运行时收到告诫。
4.4 元空间
这是
从 JDK 8 版本开始引入的
,
它是一个
可调整巨细的内存
地区,并
从本机内存中分配
。元空间保存类元数据,它不是连续的内存位置。
每当 Metaspace 到达为其分配的最大巨细时,Java 就会触发自动 GC 来开释 Metaspace 内存。
元空间选项包罗 -XX:MetaspaceSize=size和-XX:MaxMetaspaceSize=size
5. 垃圾收集
Java 程序编译并转换为字节码,并在 JVM(Java 虚拟机)上运行。Java 程序的对象在该程序的专用堆内存上创建。随着时间的推移,会创建更多对象,而且程序不再需要某些对象(未引用和取消范围的对象)。垃圾收集是 Java 执行自动内存管理并通过删除未引用的对象来开释内存空间的过程。
JVM 采取了不同的垃圾收集算法。垃圾收集算法检查内存中每个引用的对象,别的对象则被视为垃圾收集。
5.1 GC 算法的范例
以下是 JVM 可用的 4 种 GC 算法。
并行 GC
串行 GC
并发标记和渗透
G1 垃圾优先
5.1.1 并行 GC
专为具有中等或大量数据的
多线程应用程序
而设计,在多处置惩罚器环境中运行良好。但它会在垃圾收集期间冻结所有应用程序线程。JVM 选项为-XX:+UseParallelGC,您可以利用 来设置并行线程数-XX
arallelGCThreads=<NoOfThreads>。
5.1.2 串行 GC
主要设计用于
单线程
环境。与并行 GC 雷同,它还会在垃圾收集期间冻结所有应用程序线程。JVM 选项为-XX:+UseSerialGC。
5.1.3 并发标记和渗透(CMS)
这是一个并发 GC,旨在紧缩 GC 停息时间,而且
不需要制止正在运行的应用程序来执行 GC
。这就是为什么与串行或并行 GC 相比,此过程较慢的原因。它利用多线程进行垃圾收集,而且可以与垃圾收集器共享处置惩罚器资源。JVM 选项是-XX:+UseConcMarkSweepGC
5.1.4 G1垃圾收集器(G1GC)
这是另一种最高效的并发 GC,专为具有大量内存的多处置惩罚器环境而设计。JVM 选项为-XX:+UseG1GC
5.2 选择 GC 算法的参数
除非您对 GC 时间有特定要求并需要添加其他规范,否则最好让 JVM 自行选择 GC 算法。
如果您想要选择和设置 GC 算法,那么需要考虑一些参数,如堆巨细、CPU 核心数量、应用程序数据集量、吞吐量、停息时间、延迟。
堆巨细
- 分配给 JVM 的总内存量。堆巨细越大意味着 GC 需要更多时间。此外,与较少的堆内存相比,较大的堆内存意味着 JVM 触发 GC 的频率不会那么高。JVM 选项为-Xms=<n>
,-Xmx=<n>
其中
-Xms
表示最小值,
-Xmx
表示最大值。
CPU 核心 -
GC 算法随 CPU 核心数而变化。其中一些设计用于单核 CPU,一些设计用于多核 CPU。
应用程序数据集 -
这指的是应用程序利用的对象数量。创建更多新对象会导致填满年轻代空间,而且需要更多 GC 时间来开释内存。
吞吐量 -
完成应用程序使命所需的总时间(GC 之外)的百分比。它与分配给 JVM 的内存成反比。
停息时间
- GC 算法在内存回收期间制止应用程序所花费的时间。它因不同的 GC 算法而异。JVM 选项为-XX:MaxGCPauseMillis=<N>
延迟 -
这是应用程序的响应时间,直接取决于 GC 停息时间。
根据上述参数,您必须选择最适合您应用程序的 GC 算法。比方,
如果应用程序较小且利用较小的数据集,而且在单处置惩罚器上运行而没有停息时间要求,则利用串行 GC。
如果应用程序性能是最高优先级,则利用并行 GC。
当应用程序的响应时间很重要时,请利用 G1GC 或 CMS,因为它不会在运行 GC 时保留应用程序。
检查 JVM 根据您的硬件设置将选择的默认 GC 的一种方法是利用-XX:+PrintCommandLineFlags选项。打开您的命令行选项并运行java -XX:+PrintCommandLineFlags命令。
上述PrintCommandLineFlags命令根据您运行命令的硬件设置表现 JVM 选择的默认 GC。
6. 总结
以上就java8后面几个版本的jdk的jvm内存架构和GC算法根本知识分享,整理算是比较过细,喜好的小伙伴可以点赞收藏好。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
耶耶耶耶耶
金牌会员
这个人很懒什么都没写!
楼主热帖
为什么你应该停止依赖Jenkins的插件? ...
蜻蜓优化算法(Matlab完整代码实现) ...
集合论第6-8章
axios&spring前后端分离传参规范总结 ...
SQL 教程之 10 个 SQL 操作用于 80% 的 ...
关于Maven的使用
Python知识点(史上最全)
腾讯云多媒体文件处理总结
JVM常用调优配置参数
20220319编译OpenHarmony-v3.1-beta出 ...
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
物联网
移动端开发
分布式数据库
Mysql
容器及微服务
快速回复
返回顶部
返回列表