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&#…

python打开方式错误_浅谈python 调用open()打开文件时路径出错的原因

昨晚搞鼓了一下python的open&#xff08;&#xff09;打开文件 代码如下 def main(): infile open("C:\Users\Spirit\Desktop\bc.txt",r) data infile.read() print(data) main() 然而结果总报错invaild argument 或者cant found such file *** 查找问题后 发现是由…

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

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

mysql sql 去除重复行_mysql – sql自连接表删除重复行

我有下表&#xff1a;╔════════╦════════════╗║ USERID ║ LANGUAGEID ║╠════════╬════════════╣║ 1 ║ 2 ║║ 1 ║ 7 ║║ 1 ║ 8 ║║ 2 ║ 10 ║║ 2 ║ 3 ║╚════════╩════════════╝现在我想为每…

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;风华正茂的青年才…

易语言 字段重复_使对易失性字段的操作原子化

易语言 字段重复总览 易失性字段的预期行为是&#xff0c;它们在多线程应用程序中的行为应与在单线程应用程序中的行为相同。 禁止它们表现相同的方式&#xff0c;但是不能保证它们表现相同的方式。 Java 5.0中的解决方案是使用AtomicXxxx类&#xff0c;但是这些类在内存&…

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

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

qt4 连接mysql_Qt4访问mysql 数据库的简单教程

编译问题&#xff1a;1、系统中安装有VC&#xff0c;所以头文件冲突手工修改makefile删除所有-I 加载VC头文件的项目2、mysql cannot find -llibmysql指定libmysql.a的路径-LQt 4 访问 mysql 数据库的简单教程云帆 2006/5/18因为目前无法使用linux&#xff0c; 所以 Qt 4.1.2 是…

python多个函数_什么是在Python中使用多个构造函数的干净的、pythonic的方法?

其实None对于“魔法”价值观来说要好得多&#xff1a;class Cheese(): def __init__(self, num_holes None): if num_holes is None: ... 现在&#xff0c;如果您想完全自由地添加更多参数&#xff1a;class Cheese(): def __init__(self, *args, **kwargs): #args -- tuple o…

Java 8和Java 14之间的新功能

从版本9开始&#xff0c;Java每6个月就会有新功能&#xff0c;因此很难跟踪这些新更改。 互联网上的大多数信息都描述了最近两个Java版本之间的变化。 但是&#xff0c;如果您的情况与我相似&#xff0c;则说明您使用的不是Java的最新版本&#xff0c;而是使用了较旧的Java版本…

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

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

python io_NumPy IO

NumPy IO Numpy 可以读写磁盘上的文本数据或二进制数据。 NumPy 为 ndarray 对象引入了一个简单的文件格式&#xff1a;npy。 npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。 常用的 IO 函数有&#xff1a; load() 和 save() 函数是读写文件数组数据的两个…

Java 14:instanceof的模式匹配

Java 14引入了pattern Matching for instanceof &#xff08;另一种预览语言功能&#xff09; &#xff0c;从而消除了在使用instanceof时进行强制转换的需要。 例如&#xff0c;考虑以下代码&#xff1a; if (obj instanceof String) { String s (String) obj; System.out.pr…

centos7 mysql启动后端口_centos7 修改mysql5.7默认端口后启动异常

关闭selinux的方法有两种&#xff1a;临时关闭和永久关闭。查看selinux的状态&#xff1a;sestatus[root162-219-29-3 ~]# sestatusSELinux status: enabledSELinuxfs mount: /sys/fs/selinuxSELinux root directory: /etc/selinuxLoaded policy name: targetedCurrent mode: e…

computed怎么使用_Vuex 基本使用

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

自然数 素数 质数_在Java中获取素数的无限列表

自然数 素数 质数一个常见的问题是确定数字的素因式分解。 蛮力方法是审判部门&#xff08; 维基百科 &#xff0c; 可汗学院 &#xff09;&#xff0c;但是如果必须考虑多个数字&#xff0c;这需要大量的浪费工作。 一种广泛使用的解决方案是Eratosthenes筛&#xff08; 维基…

mysql 大数据 join_MySQL JOIN算法原理

MySQL的JOIN相关操作&#xff0c;是通过“嵌套循环连接算法&#xff0c;NLJ”或者该算法的优化变体“块嵌套循环连接算法&#xff0c;BNLJ”来实现的。##### 嵌套循环连接算法两个表join时&#xff0c;可以简单理解为两层for循环&#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…