我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何分析Java性能优化中的垃圾回收机制

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何分析Java性能优化中的垃圾回收机制

这篇文章将为大家详细讲解有关如何分析Java性能优化中的垃圾回收机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

★JVM 的内存空间

  在 Java 虚拟机规范中,提及了如下几种类型的内存空间:

◇栈内存(Stack):每个线程私有的。
◇堆内存(Heap):所有线程公用的。
◇方法区(Method Area):有点像以前常说的“进程代码段”,这里面存放了每个加载类的反射信息、类函数的代码、编译时常量等信息。
◇原生方法栈(Native Method Stack):主要用于 JNI 中的原生代码,平时很少涉及。

★垃圾回收机制简介

  其实 Java 虚拟机规范中并未规定垃圾回收的相关细节。垃圾回收具体该怎么搞,完全取决于各个 JVM 的设计者。所以,不同的 JVM 之间,GC 的行为可能会有一定的差异。下面咱拿 SUN 官方的 JVM 来简单介绍一下 GC 的机制。

◇啥时候进行垃圾回收?

  一般情况下,当 JVM 发现堆内存比较紧张、不太够用时,它就会着手进行垃圾回收工作。但是大伙儿要认清这样一个残酷的事实:JVM 进行 GC 的时间点是无法准确预知的。因为 GC 启动的时刻会受到各种运行环境因素的影响,随机性太大。
  虽说咱们无法准确预知,但如果你想知道每次垃圾回收执行的情况,还是蛮方便的。可以通过 JVM 的命令行参数“-XX:+PrintGC”把相关信息打印出来。
  另外,调用 System.gc() 只是建议 JVM 进行 GC。至于 JVM 到底会不会真的去做,只有天晓得。所以,通常不建议自己手动调用 System.gc(),还是让 JVM 自行决定比较好。另外,使用 JVM 命令行参数“-XX:+DisableExplicitGC”可以让 System.gc() 不起作用。

◇谁来负责垃圾回收?

  一般情况下,JVM 会有一个或多个专门的垃圾回收线程,由它们负责清理回收垃圾内存。

◇如何发现垃圾对象?

  垃圾回收线程会从“根集(Root Set)”开始进行对象引用的遍历。所谓的“根集”,就是正在运行的线程中,可以访问的【引用变量】的集合(比如所有线程当前函数的参数和局部变量、当前类的成员变量等等)。垃圾回收线程先找出被根集直接引用的所有对象(不妨叫集合1),然后再找出被集合1直接引用的所有对象(不妨叫集合2),然后再找出被集合2直接引用的所有对象......如此循环往复,直到把能遍历到的对象都遍历完。
  凡是从“根集”通过上述遍历可以到达的对象,都称为可达对象或有效对象;反之,则是不可达对象或失效对象(也就是垃圾)。

◇如何清理/回收垃圾?

  通过上述阶段,就把垃圾对象都找出来。然后垃圾回收线程会进行相应的清理和回收工作,包括:把垃圾内存重新变为可用内存、进行内存的整理以消除内存碎片、等等。这个过程会涉及到若干算法,限于篇幅,咱就不深入聊了。

◇分代

  早期的 JVM 是不采用分代技术的,所有被 GC 管理的对象都存放在同一个堆里面。这么做的缺点比较明显:每次进行GC都要遍历所有对象,开销很大。其实大部分的对象生命周期都很短(短命对象),只有少数对象比较长寿;在这些短命对象中,又只有少数对象占用的内存空间大;其它大量的短命对象都属于小对象(很符合二八原理)。
  有鉴于此,从 JDK 1.2 之后,JVM 开始使用分代的垃圾回收(Generational Garbage Collection)。JVM 把 GC 相关的内存分为“年老代”(Tenured)和“年轻代”(Nursery)、“持久代”(Permanent,对应于 JVM 规范的“方法区”)。【大部分】对象在刚创建时,都位于“年轻代”。如果某对象经历了几轮 GC 还活着(大龄对象),就把它移到“年老代”。另外,如果某个对象在创建时比较大,可能就直接被丢到年老代。经过这种策略,使得年轻代总是保存那些短命的小对象。在空间尺寸上,“年轻代”相对较小,而“年老代”相对较大。
  因为有了分代技术,JVM 的 GC 也相应分为两种——主要收集(Major Collection)和次要收集(Minor Collection)。“主要收集”同时清理年老代和年轻代,因此开销很大,不常进行;“次要收集”仅仅清理年轻代,开销很小,经常进行。

★GC对性能会有啥影响?

  刚才介绍了GC的大致原理,那GC对性能会造成哪些影响捏?主要有如下几个方面:

◇造成当前运行线程的停顿

  早期的 GC 比较弱智。在它工作期间,所有其它的线程都被暂停(以免影响垃圾回收工作)。等到 GC 干完活,其它线程再继续运行。所以,早期 JDK 的 GC 一旦开始工作,整个程序就会陷入假死状态,失去各种响应。
  经过这些年的技术改进(包括采用分代技术),从 JDK 1.4 开始,GC 已经比较精明了。在它干活期间,只是偶尔暂停一下其它线程的运行(从长时间假死变为暂时性休克)。

◇遍历对象引用的开销

  试想如果JVM中的对象很多,那遍历完所有可达对象肯定是比较费劲的工作,这个开销可不小。

◇清理和回收垃圾的开销

  遍历完对象引用之后,对垃圾的清理和回收也有较大的开销。这部分开销可能包括复制内存块、更新对象引用等等。

★几种收集器

◇两个性能指标

  因为今天聊的是性能的话题,必然会提到衡量 GC 性能的两个重要指标:吞吐量(Throughput)和停顿时间(Pause Time)。吞吐量这个词不是很直观,解释一下:就是 JVM【不用于】GC 的时间占总时间的比率。“吞吐量”是越大越好,“停顿时间”是越小越好。
  不同的应用程序对这两个指标的关注点不一样(后面具体会说),也就是所谓的“众口难调”。很多 JVM 厂商为了迎合“众口”,不得不提供多种几种垃圾收集器供使用者选择。不同的收集器,采用的收集策略是不一样的,下面具体介绍。

◇串行收集器(Serial Collector)

  使用命令行选项“-XX:+UseSerialGC”指定。
  这种收集器是最传统的收集器。它使用单线程进行垃圾回收,对于“单 CPU 机器”比较合适。另外,小型应用或者对上述两个指标没有特殊要求的,可以使用串行收集器。

◇并行收集器(Parallel Throughput Collector)

  顾名思义,这种收集器使用多个线程进行垃圾回收以达到高吞吐量。垃圾回收线程的数量通过命令行选项“-XX:ParallelGCThreads=n”指定。可以设置该数值以便充分利用“多CPU 或 多核”。
  当使用命令行选项“-XX:+UseParallelGC”时:它会针对年轻代使用多个垃圾回收线程,对年老代依然使用单个线程的串行方式。此选项最早在JDK 1.5引入。
  当使用命令行选项“-XX:+UseParallelOldGC”时:它针对年轻代和年老代都使用多个垃圾回收线程的方式。不过此选项从 JDK 1.6 才开始引入。

◇并发收集器(Concurrent Low Pause Collector)

  使用命令行选项“-XX:+UseConcMarkSweepGC”指定。
  这种收集器优先保证程序的响应。它会尽量让垃圾回收线程和应用自身的线程同时运行,从而降低停顿时间。此选项从JDK 1.4.1开始支持。

◇增量收集器(Incremental Collector)

  自从 JDK 1.4.2 以来,SUN 官方就停止维护该收集器了。所以俺就节省点口水,不多说了。

★如何降低GC的影响?

◇尽量减少堆内存的使用

  由于 GC 是针对存储在堆内存的对象进行的。咱们如果在程序中减少引用对象的分配(也就相应降低堆内存分配),那对于提高 GC 的性能是很有帮助滴。上次“字符串过滤实战”的帖子给出了一个例子,示范了如何通过降低堆内存的分配次数来提升性能。

◇设置合适的堆内存大小

  JVM 的堆内存是有讲究的,不能太大也不能太小。如果堆内存太小,JVM 老是感觉内存不够用,可能会导致频繁进行垃圾回收,影响了性能;如果堆内存太大,以至于操作系统的大部分物理内存都被 JVM 自个儿霸占了,那可能会影响其它应用程序甚至操作系统本身的性能。
  另外,年轻代的大小(或者说“年轻代”与“年老代”的比值)对于 GC 的性能也有明显影响。如果年轻代太小,可能导致次要收集很频繁;如果年轻代太大,导致次要收集的停顿很明显。
  JVM 提供了若干和堆内存大小相关的命令行选项,具体如下:
------------------------------
-Xms  设置初始堆内存
-Xmx  设置最大堆内存
-Xmn  设置年轻代的大小
-XX:NewRatio=n  设置年轻代与年老代的比例为“n”
-XX:NewSize=n  设置年轻代大小为“n”
------------------------------
  一般情况下,JVM 的默认参数值已经够用。所以没事儿别轻易动用上述选项。如果你非调整不可,一定要做深入的性能对比测试,保证调整后的性能确实优于默认参数值。

◇吞吐量和停顿的取舍

  前面提到了不同应用的众口难调。常见的口味有两种:(1)看重吞吐量,对停顿时间无所谓;(2)侧重于停顿时间。
  对于某些在后台的、单纯运算密集型的应用,属于第一种。比如某些科学计算的应用。这时候建议使用并行收集器。
  对于涉及用户 UI 交互的、实时性要求比较高、程序需要快速响应的,属于第二种。比如某些桌面游戏、某些电信交换系统。这时候建议使用并发收集器。

关于如何分析Java性能优化中的垃圾回收机制就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何分析Java性能优化中的垃圾回收机制

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何分析Java性能优化中的垃圾回收机制

这篇文章将为大家详细讲解有关如何分析Java性能优化中的垃圾回收机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。★JVM 的内存空间  在 Java 虚拟机规范中,提及了如下几种类型的内存
2023-06-02

Java中的垃圾回收机制是如何工作的?如何优化Java的垃圾回收?(Java的垃圾回收器如何运作?有哪些策略可以优化Java的垃圾回收性能?)

Java垃圾回收机制通过根引用扫描、图遍历、标记和清除过程回收不再使用的对象。优化策略包括减少对象分配、使用大对象、避免循环引用、调整GC参数和使用最新JVM版本。监控GC性能并根据特定需求优化策略至关重要。
Java中的垃圾回收机制是如何工作的?如何优化Java的垃圾回收?(Java的垃圾回收器如何运作?有哪些策略可以优化Java的垃圾回收性能?)
2024-04-02

js中垃圾回收机制如何优化

这篇文章主要介绍js中垃圾回收机制如何优化,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、数组array优化将[]赋值给一个数组对象,是清空数组的捷径(例如: arr = [];),但是需要注意的是,这种方式又创建
2023-06-15

详解 Java性能优化和JVM GC(垃圾回收机制)

Java的性能优化,JVM GC(垃圾回收机制)在学习Java GC 之前,我们需要记住一个单词:stop-the-world 。它会在任何一种GC算法中发生。stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行
2023-06-02

如何通过 Java 垃圾回收机制优化代码结构?(Java垃圾回收机制怎样优化代码结构)

在Java编程中,垃圾回收机制是一个非常重要的概念,它对于优化代码结构和提高程序性能起着关键作用。本文将详细介绍Java垃圾回收机制以及如何利用它来优化代码结构。一、Java垃圾回收机制概述Java垃圾回收机制是自动
如何通过 Java 垃圾回收机制优化代码结构?(Java垃圾回收机制怎样优化代码结构)
Java2024-12-21

Go函数性能优化:垃圾回收机制与性能的影响

垃圾回收 (gc) 对 go 函数性能有影响,因为它会暂停程序以回收内存,从而中断执行。优化策略包括:减少分配使用池避免循环中的分配使用预分配的内存profile 应用程序Go 函数性能优化:垃圾回收机制与性能的影响前言垃圾回收 (GC
Go函数性能优化:垃圾回收机制与性能的影响
2024-05-03

JVM中垃圾回收机制的示例分析

这篇文章主要介绍了JVM中垃圾回收机制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。堆内存的划分分为三个部分(以下名词表示同一个区):新生区、新生代、年轻代养老区、
2023-06-29

PHP中垃圾回收机制的示例分析

小编给大家分享一下PHP中垃圾回收机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!如果用过C语言,那么申请内存的方式是malloc或者是calloc,
2023-06-15

深入浅析Java 中的可视化垃圾回收机制

这期内容当中小编将会给大家带来有关深入浅析Java 中的可视化垃圾回收机制,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。基础当谈到释放不再使用的内存,垃圾回收已经在很大程度上取代了早期技术,比如手动内存管
2023-05-31

kubernetes中垃圾回收机制的示例分析

这篇文章主要介绍了kubernetes中垃圾回收机制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一:前言Kubernetes系统在长时间运行后,Kubernete
2023-06-04

PHP接口性能优化之GC(垃圾回收)机制调优(PHP接口中GC机制的性能优化方法)

PHP接口性能优化之GC(垃圾回收)机制调优本篇文章重点介绍了优化PHP接口中GC(垃圾回收)机制的方法,以提高性能。优化方法包括:减少不必要的对象创建优化对象引用禁用延迟GC调整GC设置使用特定GC算法利用第三方扩展(如igbinary、xcache)通过这些优化,可以显著提高PHP接口在处理大量数据或复杂计算时的响应速度。
PHP接口性能优化之GC(垃圾回收)机制调优(PHP接口中GC机制的性能优化方法)
2024-04-02

怎样进行Java垃圾回收机制的原理分析

本篇文章为大家展示了怎样进行Java垃圾回收机制的原理分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java垃圾回收监控和分析工具Java VisualVMJava VisualVM是在Java
2023-06-17

揭秘Java性能调优的奥秘:垃圾回收调优与线程池优化

GC调优和线程池优化是Java性能调优的重要方面。本文将揭秘Java性能调优的奥秘,并详细介绍GC调优和线程池优化的方法。
Java调优2024-11-30

Linux中如何进行JAVA虚拟机的垃圾回收

本篇文章给大家分享的是有关Linux中如何进行JAVA虚拟机的垃圾回收,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。JVM 的 GC的日志是以替换的方式(>)写入的,而不是追加
2023-06-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录