JVM垃圾收集和优化

总览

在对系统进行性能相关问题的故障排除时,内存优化是一个需要深入分析每个系统在内存中存储的内容,存储时间和访问模式的地方。 这篇文章是要在背景信息上进行注释,并在此工作中要注意一些要点,这些工作要专门针对基于Java的实现,因为深入了解JVM行为在此过程中非常有益。

Java语言通过在很大程度上照顾内存管理,从而将重点放在其余逻辑上,为开发人员提供了许多便利。 仍然对Java到底是如何做的有一个很好的了解,合理化我们在Java实现中遵循的几种最佳实践,并帮助更好地设计程序,并认真思考某些方面,从长远来看,这些方面以后可能导致内存泄漏和系统稳定性。 Java Garbage Collector在这方面起着重要作用,它负责通过删除内存垃圾来释放内存。

这些信息可广泛获得,但我在这里汇总以供参考。 :)

JVM使Java代码能够以独立于硬件和OS的方式运行。 它在由操作系统充当物理机的另一种抽象的操作系统分配给自己的进程的内存位置上运行。

JVM可以基于[1]中发布​​的开放标准来实现,众所周知的实现是Oracle Hotspot JVM,几乎与Android OS中使用的开放源代码版本OpenJDK,IBM J9,JRockit和Dalvik VM有所不同。

简而言之,JVM使用从平台分配给它的资源来加载并执行已编译的Java字节代码,它在上面运行。

类加载器

将字节码加载到JVM内存中(加载,链接(验证,准备,解决–>如果发出失败的NoClassDef发现异常),初始化),引导类加载器,扩展类加载器,应用程序类加载器

内存和运行时数据区

尽管它并不全面,但它涵盖了以下几个重要部分。

  • 本机方法堆栈– Java本机库堆栈,它与平台有关,主要是用C语言编写的。
  • JVM堆栈(每个线程保留当前执行的方法堆栈跟踪。如果未设置适当的中断,则递归方法调用可能导致堆栈被填充和溢出(java.lang.StackOverFlowError) 。-Xss JVM选项允许配置堆栈大小。),PC寄存器(程序计数器,指向每个线程要执行的下一条指令。)
  • 方法区域(存储类数据,大小受XX:MaxPermSize限制 ,PermGen空间默认为64MB,如果要服务于加载数百万个类的大型服务器应用程序,则可以通过增加调整来避免OOM问题:PermGen空间。从Java 8开始)自此以后,尽管允许对其进行微调和限制,但默认情况下java8中将此PermGen空间称为没有限制的元空间),Heap(Xms,Xmx),运行时常量池

执行引擎

该引擎执行通过类加载器分配给运行时数据区域的字节码。 它利用解释器,垃圾收集器,热点分析器,JIT编译器来优化程序执行。

有关JVM体系结构的更多详细信息,请参见[2]。

现在我们知道了垃圾收集器在JVM体系结构中的位置。 让我们深入了解内部。

垃圾收集器

这是Java自动内存管理过程,它删除了不再使用的对象。 接下来是问题,它如何决定是否使用该对象。

它定义了两类对象,

活动对象 –从另一个对象引用的可访问对象。 最终,引用链接将到达根,该根是创建整个对象图的主线程。 死对象 –只是躺在堆中的其他对象未引用的不可访问对象。

此分类和垃圾回收基于以下两个事实。

1.大多数对象在创建后很快就变得无法访问。 通常,短暂对象仅存在于方法上下文中。 2.老物件很少指年轻物件。 例如,寿命长的缓存几乎不会从中引用较新的对象。

新创建的对象实例驻留在Java堆中,该堆可以进行不同的生成,如下所示。 垃圾收集是通过称为“垃圾收集器”的守护程序线程完成的,该线程将对象引导通过堆中的不同空间。

垃圾收集分3个步骤进行。

1.标记 –从根开始并遍历对象图,将可访问对象标记为活动对象。

2.扫描 –删除未标记的对象。 3.紧凑 –对内存进行碎片整理,使活动对象的分配连续。 这被认为是最耗时的过程。

堆区域划分如下。

旧的(终身使用的)代 –可以存活很长时间的对象,请留在这里,直到其被标记为无法访问并在遍及整个堆的主要垃圾收集中清理为止。
年轻一代 –进一步分为3个伊甸园空间和2个幸存者空间。 垃圾收集分为两个阶段:“次要”或“主要”。 这两个垃圾回收都是停止运行的操作,它们停止所有其他内存访问。 应用程序可能不会感觉到次要GC,因为它仅扫描年轻一代空间会很小。

垃圾收集器

内存生命周期如下图所示,如上图所示。

1.新创建的对象驻留在Eden空间中。 (就像人类从伊甸园开始的一样:)在伊甸园空间变满之前,它一直在不断增加新的物体。

2.当Eden空间已满时,将运行次要GC,标记活动对象,然后将这些活动对象移至“幸存者从”空间,然后扫掠空闲的Eden空间。

3.然后在程序运行时继续用新对象填充Eden空间。 现在,当Eden空间已满时,我们先前也已将“幸存者来自”空间中的对象移动了。 次要GC在这两个空间中运行标记对象,然后将剩余的活动对象整体移至其他幸存者空间。 想知道为什么不将有生命的物体从伊甸园空间复制到“幸存者从”的剩余空间,而不是全部转移到另一个幸存者空间? 好吧,事实证明,在紧凑的步骤中,将所有其他对象移到另一个对象上要比压缩其中带有对象的区域更为有效。

4.此循环将在幸存者空间之间重复移动对象,直到达到配置的阈值(-XX: MaxTenuringThreshold 。 (它跟踪每个对象生存了多少个GC循环)。 当达到阈值时,这些对象将被移至保管空间。

5.随着时间的流逝,如果使用权空间也被填满,则主GC将启动并遍历整个堆内存空间,以执行GC步骤。 这种暂停可以在人际互动中感觉到,这是不希望的。

当内存泄漏或长时间驻留大量高速缓存时,使用期限将被占用。 在这种时候,这些对象甚至可能没有被检测为死亡。 这会导致主要GC频繁运行,因为它检测到永久性空间已满,但是由于无法清除任何内容,因此无法清理足够的内存。

当内存不足时,日志中的错误“ java.lang.OutOfMemoryError”将清楚地提示我们。 另外,如果我们看到频繁使用大量内存的CPU频繁运行,则可能是由于某些内存处理问题需要引起注意而导致GC频繁运行的征兆。

在专注于JVM微调(专注于内存利用率)时,主要的决定因素是响应性/延迟吞吐量中更关键的因素。 如果在批处理中吞吐量是最重要的,那么如果可以提高主要吞吐量,我们可以在运行主要GC时暂停一下来妥协。 因为应用程序偶尔的响应速度可能不是那里的问题。

另一方面,如果像在基于UI的应用程序中一样,响应性至关重要,则应尝试避免使用大型GC。 也就是说,这样做并没有帮助。 例如,我们可以通过增加年轻一代的空间来延迟大型GC。 但是随后,小型GC将开始花费大量时间,因为它现在需要遍历并压缩巨大的空间。 因此,要拥有正确的尺寸,就需要谨慎地实现年轻人和老年人之间的正确比例。 有时,这甚至可以进入应用程序设计细节,以通过对象创建模式和缓存位置来微调内存使用情况。 这将是另一篇文章的主题,该文章分析堆转储和火焰图,以确定要缓存的最佳内容。

垃圾收集器

由于垃圾回收的作用对应用程序的性能有很大的影响,因此工程师们花费了大量的精力来改进它。 结果是,我们可以根据需求选择最佳的垃圾收集器。 以下是不完整的选项列表。

1.串行收集器

在单个线程中运行。 仅适用于基本应用。

一个线程执行垃圾回收。 它只会使世界处于标记和重新标记阶段。 其余的工作在应用程序运行时完成,并且不等待旧的版本已满。 当内存空间大,具有大量CPU来满足并发执行时,以及当应用程序要求最短的暂停时间和响应能力成为关键因素时,这是一个不错的选择。 过去,这是大多数Web应用程序中最受欢迎的。

3.并行收集器

该收集器使用多个CPU。 它等待旧的一代充满或接近充满,但是当它运行时,它停止了世界。 多个线程进行标记,清除和压缩,使垃圾收集更快。 当内存不是很大并且CPU数量受到限制时,这是一个很好的选择,可以满足对吞吐量的要求,可以承受暂停。

4. G1(垃圾优先)收集器(1.7以上)

通过允许配置(例如,GC运行时暂停时间),此选项可提高垃圾收集的可预测性。 据说在并行性和并发性两方面都具有优势。 它将内存划分为多个区域,每个区域都被视为伊甸园,幸存者或保有权空间。 如果该区域有更多无法访问的对象,则将首先对该区域进行垃圾收集。

版本中的默认垃圾收集器

  • Java 7 –并行GC
  • Java 8 –并行GC
  • Java 9 – G1 GC
  • Java 10 – G1 GC
  • Java 11 – G1 GC(ZGC与Epsilon一起作为实验功能提供)
  • Java 12 – G1 GC(引入了Shenandoah GC。仅适用于OpenJDK。)

垃圾收集器的优化参数

除非有默认设置要解决的问题,或者是经过长时间的考虑,并且经过长时间的生产级别的负载模式验证后才能确定,否则调优JVM的经验法则是不这样做的。 这是因为Java Ergonomics已经取得了很大进步,并且如果应用程序不难看的话,大多数时候将能够执行很多优化。 在[5]中可以找到选项的完整列表,包括配置堆空间的大小,阈值,要使用的垃圾收集器的类型等。

诊断

除堆转储外,以下配置还有助于通过GC行为诊断内存问题。

-XX:-PrintGCDetails –打印垃圾收集的详细信息。
-Xloggc:<文件名> –将GC日志记录详细信息打印到给定文件。
-XX:-UseGCLogFileRotation –完成上述配置后,启用GC日志文件旋转。 -XX:-HeapDumpOnOutOfMemoryError –如果发生OOM错误,则转储堆内容以进行进一步分析。 -XX:OnOutOfMemoryError =” <cmd args =””>; <cmd args =””>” –如果发生OOM错误,则要运行的命令集。 遇到错误时允许执行任何自定义任务。

我们将在另一篇文章中讨论诊断和分析细节。

干杯!

[1] – https://docs.oracle.com/javase/specs/index.html


[2] – https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.6


[2] – Oracle垃圾收集调优指南–

https://docs.oracle.com/javase/9​​/gctuning/ergonomics.htm#JSGCT-GUID-DB4CAE94-2041-4A16-90EC-6AE3D91EC1F1

[3] –新的Java垃圾收集器–

https://blogs.oracle.com/javamagazine/understanding-the-jdks-new-superfast-garbage-collectors

[4] –可用的收藏家–

https://docs.oracle.com/cn/java/javase/13/gctuning/available-collectors.html#GUID-F215A508-9E58-40B4-90A5-74E29BF3BD3C

[5] – JVM选项–

https://www.oracle.com/technetwork/articles/java/vmoptions-jsp-140102.html

翻译自: https://www.javacodegeeks.com/2020/05/jvm-garbage-collection-and-optimizations.html

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

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

相关文章

redis desktop manager连不上redis_Redis安装教程

Ⅰ 简介Redis 是一个开源&#xff08;BSD许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构&#xff0c;如字符串&#xff08;strings&#xff09;&#xff0c;散列&#xff08;hashes&#…

c++如何将int数组中的值取出*号运算符_如何用动态规划巧妙解决 “双十一” 购物时的凑单问题?羊毛薅起来!!!...

点击上方“程序员大白”&#xff0c;选择“星标”公众号重磅干货&#xff0c;第一时间送达今年过去的 “双十一” &#xff0c;你有薅到羊毛吗&#xff1f;每年的双十一&#xff0c;会有各种促销活动&#xff0c;比如 “满 300元减 80 元”。假如你女朋友的购物车中有 n 个(n &…

python操作界面_Python使用PyQt5的Designer工具创建UI界面

一、Designer-UI编辑器 Designer是pyqt5-tools带的工具&#xff0c;默认可以在Python安装目录下找到的。我的之前项目导入过pyqt5-tools&#xff0c;所以我直接全盘搜索到了。打开designer后&#xff0c;我们可以编辑我们想要的UI界面&#xff0c;下面是我编辑的测试界面&#…

python统计词频_Python统计四六级考试的词频

Python统计四六级考试的词频此文首发于公众号 「Python知识圈」&#xff0c; 欢迎直接去公众号查看阅读文本大概需要 4.6 分钟。今天是教师节&#xff0c;先祝天下所有老师教师节快乐&#xff0c;感谢您在我学生时代对我的谆谆教诲。现在是开学之初&#xff0c;风华正茂的青年才…

python爬虫数据可视化_适用于Python入门者的爬虫和数据可视化案例

本篇文章适用于Python小白的教程篇&#xff0c;如果有哪里不足欢迎指出来&#xff0c;希望对你帮助。 本篇文章用到的模块&#xff1a; requests,re,os,jieba,glob,json,lxml,pyecharts,heapq,collection 首先 本文我们的目的 抓取周杰伦的所有歌曲&#xff0c; 歌词&#xff0…

mysql中如何卸载插件_Eclipse中如何卸载插件

很久没用Eclipse了&#xff0c;今天打开的时候&#xff0c;突然报Android开发插件需要更新。打开插件管理页面&#xff0c;更新Android插件&#xff0c;又提示和旧版本有冲突&#xff0c;心想只能卸载了重新安装了。找了半天没找到在哪下载&#xff0c;把Eclipse目录下的plugin…

computed怎么使用_Vuex 基本使用

简单介绍iPhone X 是 iPhone, Vuex 并不是 Vue.我们查看官方文档可以知道&#xff1a;Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。怎么理解呢&#xff1f;就拿我两位数的资产的银行卡来说吧&#xff0c;基本的存钱取钱&#xff0c;就是状态管理。怎么用我们将以一个简…

windows安装python3步骤_Windows下python3和python2安装与一起使用

一、python2和python3安装 2、安装步骤&#xff0c;直接双击运行&#xff0c;记得勾选添加环境变量就可以。图片1.png 3、安装已经选择了添加这个环境变量&#xff0c;所以不用再去配置。 如果没有勾选&#xff0c;得自己去设置。 鼠标右键我的电脑 -> 属性 -> 点击高级系…

mysql ondelete_MySQL on delete cascade语句

在本教程中&#xff0c;您将学习如何使用MySQL ON DELETE CASCADE引用操作来执行外键从多个相关表中删除数据。在上一个教程中&#xff0c;我们学习了如何使用单个DELETE语句从一个或多个相关表中删除数据。但是&#xff0c;MySQL提供了一种更为有效的方法&#xff0c;称为ON D…

python构建二叉树_BinaryTree:学习二叉树的Python库

Python部落(python.freelycode.com)组织翻译&#xff0c;禁止转载&#xff0c;欢迎转发。简介&#xff1a; 您是否在为考试、作业或技术面试学习二叉树&#xff1f; Binarytree是一个Python库&#xff0c;它通过一个简单的API生成二叉树&#xff0c;可以进行检查和操作。它让您…

mysql union as 注入_sql注入入门 之 mysql 常规注入 [ union方式 ]

1,常规数字型 mysql 实例注入点,如下:1https://www.vuln.com/md_materia_profile_view.php?viewid22,依旧先尝试下经典的单引号,如下,虽然没暴露出明显的数据库报错信息,但我们发现,此时返回的页面已经异常了,经验判断,十有八九是个注入点,先不管那么多,我们继续1https://www.…

gradle docker_带有Gradle的Docker容器分为4个步骤

gradle docker您是否需要通过Java Web应用程序创建Docker映像&#xff1f; 您在使用Gradle吗&#xff1f; 如果是这样&#xff0c;那么您距Docker nivana仅4步之遥。 对于此示例&#xff0c;我将使用一个简单的Spring Boot应用程序。 您可以在我的名为galoshe的Github存储库中…

python socket编程_Python学习记录-socket编程

1. OSI七层模型详解2. Python socket 什么是 Socket? Socket又称”套接字”&#xff0c;应用程序通常通过”套接字”向网络发出请求或者应答网络请求&#xff0c;使主机间或者一台计算机上的进程间可以通讯。 Python 提供了两个级别访问的网络服务&#xff1a; 低级别的网络服…

判断frame是否已创建_类的创建

1. 士兵 许三多 有一把 AK47 2. 士兵 可以开火 3. 枪 能够 发射 子弹 4. 枪 装填 子弹---增加子弹数量 class Gun:def __init__(self,type):self.type type# 刚开始枪没有子弹self.bullet_count 0def __str__(self):return ("%s 已到位" % self.type)def shoot(sel…

@select注解_Mybatis基本知识十七:Mybatis注解式开发-单表注解式开发

上一篇文章&#xff1a;《Mybatis基本知识十六&#xff1a;查询缓存之第三方查询缓存》若文中有纰漏,请多多指正&#xff01;&#xff01;&#xff01;1.前言使用Mybatis进行开发&#xff0c;不仅可以使用mapper配置文件进行开发&#xff0c;也可以使用注解的方式。映射文件中无…

maven servlet配置_第一个Servlet配置

使用IntelliJ IDEA创建一个Simple Maven项目2. Add Framework Support3. 配置Tomcat打开菜单Run -> 选择Edit Configuration 如果侧边栏没有Tomcat&#xff0c;点击“”号 -> 选择“Tomcat Server” -> 选择“Local”&#xff0c;到此画面 ,Apply -> OK4. 在Tomcat…

ad域管理与维护_U-Mail邮件系统LDAP/AD同步极大提升办公效率

每一位办公族&#xff0c;可能都遇到过这样的问题&#xff1a;1、随着信息化高速发展和企业“互联网”的深入&#xff0c;越来越多的办公平台和软件被开发出来&#xff0c;正如移动互联网端APP应用层出不穷一样&#xff0c;给人们带来了极大地便利性。2、凡事有利有弊&#xff…

c语言c99标准_C语言的灵魂指针,配合这个新增的关键字,能够生成更高效的程序...

正如我前面的文章提到的&#xff0c;C语言虽然已经比较成熟&#xff0c;但是近些年来也是有所发展的——比如增加了许多新特性。遗憾的是&#xff0c;可能因为C语言程序员的工资比不过互联网程序员&#xff0c;国内很多教材比较老旧&#xff0c;几乎不涉及近些年来C语言新增的新…

java ee的小程序_Java EE 8 –为更多设备提供更多应用程序

java ee的小程序如果我不喜欢夏天的一件事&#xff0c;那就是事实是没有太多要分享或谈论的新闻。 谁决定将Java Day Tokyo置于今年的这个无聊的时间里&#xff0c;做得很好&#xff0c;并给了我一个写关于新的和即将到来的Java EE 8规范的博客帖子的机会&#xff0c;其中丰富了…

java随机姓名_Java生成随机姓名、性别和年龄的实现示例

一、定义实体类Person&#xff0c;封装生成的数据package net.dc.test;public class Person {private String name;private String sex;private int age;public String getName() {return name;}public void setName(String name) {this.name name;}public String getSex() {r…