- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章如何有效管理JVM中的垃圾?由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
都说JVM是大牛们玩的技术,其实未必,如果面试官和你你谈到Java内存管理,那么首先,我建议你首先要了解Java垃圾收集的工作原理。 因为经常在运行JAVA应用程序时,大多数开发者是使用JVM自动帮你管理GC垃圾回收器(完全不关注,JVM自动完成回收),码农们只关注业务代码实现,不需要关注JVM是怎么管理的,对大家而言,更多人只知道程序正在运行中。但是老铁们,当你写的JAVA程序开始面临性能下降时,码农与架构师的区别就来了,所有的性能问题其实归根到底就是我们的GC回收效率变低了.
因此,让我们首先了解什么是JVM GC模型,然后,我们可以看到如何控制它并分析GC日志以查找应用程序中发生的任何差异.
自动垃圾收集是指对堆内存的查看,并识别哪些对象正在使用哪些对象,以及删除未使用的对象的过程.
首先我们看一下自动GC垃圾收集,它的步骤如下:
该过程的第一步称为标记。其实就是垃圾收集器识别哪些内存正在使用,哪些内存不在使用的地方.
如果必须扫描系统中的所有对象,将是一个非常耗时的过程.
正常删除是指移除未引用的对象,留下引用的对象和指向空闲空间的指针.
要进一步提高性能,除了删除未引用的对象外,还可以压缩剩余的引用对象.
通过将引用的对象移动到一起,这使得新的内存分配更加容易和快速.
当正在进行垃圾收集时,如果你的应用程序在该时间段内没有响应时,其实我们的期望是,GC应该花费最少的时间来回收它; 当然, 如果花费很多时间,则证明你的应用GC设置是有问题滴.
我们来看看下面的JVM内存模型,它分为不同的部分。JVM堆内存在物理上分为两部分 - Young Generation(新生代)和Old Generation(老年代).
1.首先,将所有新的对象都分配给伊Eden space(伊甸园)。两个Survivor Space(幸存者区)都是空的.
2.当Eden space(伊甸园)填满时,会触发一个小的垃圾收集.
3.引用的对象被移动到第一个幸存者空间。清除Eden space(伊甸园)时,将删除未引用的对象.
4.下次要GC回收时,Eden space(伊甸园)空间也会发生同样的事情。删除未引用的对象,并将引用的对象移动到幸存者空间。但是,在这种情况下,它们被移动到第二个幸存者空间(S1).
5.在较小的GC之后,当老化的对象达到一定的年龄阈值(在该示例中为8)时,它们从新生代晋升到老年代.
最终,将对老一代进行主要的GC回收,清理和压缩该空间.
垃圾收集是指当JVM不再需要对象时,需要将它回收,释放内存。它包括查找不再使用的对象,释放与这些对象关联的内存,并偶尔压缩堆以防止内存碎片.
垃圾收集器使用一个或多个线程来执行回收工作。一般来说,为了完成跟踪对象引用及在内存中移动对象的工作,它需要确保应用程序线程当前没有使用这些对象,如果应用程序线程正在使用对象,GC回收时会导致对象的内存位置发生变化,可能发生不可预测的事情。这就是垃圾收集器在执行某些任务时必须暂停所有应用程序线程的原因。这些暂停有时被称为Stop-The-World暂停(吊炸天,全世界都被停止,哈哈).
垃圾收集调优的第一步是**调整堆的大小。**这是因为如果堆太小,则会发生太多的GC回收回收内存次数,这会降低整体应用程序吞吐量。如果堆太大,那么GC回收次数会更少,但GC需要很长的时间,那么你的系统响应时间指标会受到影响。并行收集器特别容易受到堆大小的影响,因此如果你需要大的堆并且暂停时间较短,那么你应该尝试使用G1GC收集器.
**备注:**自从Java 9和Shenandoah垃圾收集器被视为还处于“实验性”阶段,不推荐使用并发标记扫描(CMS)收集器。但如果你正在运行在线交互式应用程序,那么系统会默认选择G1GC收集器,如果你正在运行脱机批处理应用程序,那么并行收集器应该是你的首选,这是我给大家的建议.
**堆的大小由两个值控制:**使用ms标志指定的初始值和使用mx标志指定的最大值.
-Xms1g -Xmx8g 。
堆的初始大小和最大大小,可以由JVM根据工作负载自动调整堆大小。如果JVM遇到内存压力并且观察到GC执行次数过多,它会不断增加堆,直到内存压力消失为止,或直到堆达到其最大值为止。如果内存压力很低,JVM还可以通过缩小堆大小来决定减少暂停时间。这个过程称为自适应大小调整**,**它不仅可以调整堆的整体大小,还可以调整年轻代和老代的大小和比例.
当然,如果你想调整GC行为和大小,**我建议你可以选择关闭自适应大小调整。**这可以节省JVM,这是计算堆大小所需的一小段时间。你可以通过将标志设置UseAdaptiveSizePolicy为false 来执行此操作.
-XX:-UseAdaptiveSizePolicy 。
此外,将初始堆大小设置为与最大堆大小相同的值,或将初始新生代大小设置为与最大新生代大小相同的值,这样操作可以有效地关闭自适应大小调整.
一般来说堆大小的最大设置准则就是**最大堆大小不应超过计算机上的物理内存量。**如果你运行多个JVM,则最大堆大小的总和不应超过计算机的物理内存.
在G1GC中,调整参数MaxGCPauseMillis执行以下所有优化,以尝试实现指定的暂停时间目标:
**G1GC是一个并发收集器。**这意味着当应用程序线程仍在运行时,垃圾收集进程的某些阶段可以并发运行。并且由于正在运行的应用程序可以继续产生垃圾,我们可能会遇到应用程序耗尽旧代内存而垃圾收集器仍在垃圾收集过程中的情况。也就是说,正在运行的应用程序生成的垃圾比它清理的速度快。**这种情况称为并发模式故障,**具体取决于故障发生的时间。如果您在GC日志中看到很多这些错误; 解决方案是增加堆的大小,更早地启动G1后台处理,或者通过使用更多后台线程来加速GC处理.
要更频繁地执行G1后台活动,您可以降低触发G1循环的阈值。这是通过减少InitiatingHeapOccupancyPercent标志的值来实现的.
-XX:InitiatingHeapOccupancyPercent=45 。
默认情况下,此标志设置为45。这意味着**当堆填充45%时会触发GC循环。**减少此值意味着GC会更早且更频繁地触发。但应注意的是,该值不会设置为太低而导致GC过于频繁发生的数字.
要增加后台线程数,请使用该ConcGCThreads标志.
-XX:ConcGCThreads=4 。
此标志的默认值设置为ParallelGCThreads加2 的值除以4.只要计算机上有足够的CPU可用,就可以增加此值而不会导致任何性能损失.
如果调整堆大小并调整收集器对你不起作用,**那么你可以尝试另一个收集器。如果你仍然没有取得好成绩,那么你需要考虑调整应用程序代码本身的问题了,好了,写了这么多,希望对大家有帮助.
到此这篇关于如何有效管理JVM中的垃圾?的文章就介绍到这了,更多相关JVM垃圾管理内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/m0_57081368/article/details/117892019 。
最后此篇关于如何有效管理JVM中的垃圾?的文章就讲到这里了,如果你想了解更多关于如何有效管理JVM中的垃圾?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是 C 新手,还没有真正掌握 C 何时决定释放对象以及何时决定保留对象。 heap_t 是指向结构堆的指针。 heap_t create_heap(){ heap_t h_t = (heap
我有一个问题,我不知道如何解决。问题是: char * ary = new Char[]; ifstream fle; fle.open(1.txt, ios_base::binary); fle.s
假设我在 C# 中有字符串:“我看不到你……” 我想删除(替换为空等)这些“’”符号。 我该怎么做? 最佳答案 那个“垃圾”看起来很像有人将 UTF-8 数据解释为 ISO 8859-1 或 Wi
我无法在解析方法中更改蜘蛛设置。但这绝对是一种方式。 例如: class SomeSpider(BaseSpider): name = 'mySpider' allowed_domains
在开始之前,我们先回顾一下堆是个什么玩意,大家可能都知道,我们每天创建的Java对象几乎都存放在堆上面,所以说堆是一个巨大的对象池一点都不过分,在这个对象池里面管理者数据巨大的对象实例。 在对
我想知道为什么 printf() 在提供数组且没有格式化选项时成功打印字符数组,但在使用整数数组时编译器会抛出警告并打印垃圾值。 这是我的代码: #include int main() { c
我正在研究 Scrapy 库并尝试制作一个小爬虫。 这是爬虫的规则: rules = ( Rule(LinkExtractor(restrict_xpaths='//div[@class="w
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Printing a string to a temporary stream object in C++
这个问题在这里已经有了答案: Are WebGL objects garbage collected? (2 个答案) 关闭 3 年前。 在 WebGL 中,纹理的创建和销毁使用: WebGLTex
我继承了以下代码: (为保护无辜者更改了一些名称。) package foo.bar.baz; import javax.swing.JPanel; //Main panel in the GUI c
如果我没记错的话,在某些情况下,Java 中的 lambda 会生成为匿名类实例。例如,在这段代码中,lambda 需要从外部捕获一个变量: final int local = 123456; lis
我正在阅读托管代码中的内存泄漏,想知道是否可以在 C# 不安全代码中创建它? unsafe { while(true) new int; } 我不确定如果它作为不安全代码运行,是否会被 GC
假设我有以下用 HTML 编写的网页(仅正文部分): ... function fn() { // do stu
我想知道是否有简单的命令可以删除在 latex 编译过程中生成的所有不必要的文件,例如.aux、.log 等 最好将它链接到常规的 Latex 构建命令,这样在我点击“编译”后,垃圾文件就会被删除。
Java 在 Java7 中引入了带有字符串的 switch case。我想知道使用这样的开关盒是否会产生垃圾。 例如在我的程序中, String s = getString(); switch(s)
Cevelop将 char junk 作为“未初始化的变量”对象。在这种情况下,解决问题的正确方法是什么? friend std::ostream& operator>(std::istream&
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and t
我正在编写一个发送和接收纯文本的小型 boost asio tcp 服务器和客户端。通信或多或少是请求响应。在测试期间,我想我只是向服务器发送垃圾数据,向它发送 100.000 个请求。 客户端发
我正在使用 SAX 来读取/解析 XML 文档,并且它工作正常,除了这个特定的站点,在该站点中 eclipse 告诉我“文档元素之后的垃圾”并且我没有返回任何数据 http://www.zachblu
这是我的 Scrapy 爬虫代码。我正在尝试从网站中提取元数据值。没有元数据在一个页面上出现多次。 class MySpider(BaseSpider): name = "courses"
我是一名优秀的程序员,十分优秀!