James-你有效地管理JVM的垃圾了吗?是时候把垃圾拿出来了!

都说JVM是大牛们玩的技术,其实未必,如果面试官和你你谈到Java内存管理,那么首先,我建议你首先要了解Java垃圾收集的工作原理。 因为经常在运行JAVA应用程序时,大多数开发者是使用JVM自动帮你管理GC垃圾回收器(完全不关注,JVM自动完成回收),码农们只关注业务代码实现,不需要关注JVM是怎么管理的,对大家而言,更多人只知道程序正在运行中。但是老铁们,当你写的JAVA程序开始面临性能下降时,码农与架构师的区别就来了,所有的性能问题其实归根到底就是我们的GC回收效率变低了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,让我们首先了解什么是JVM GC模型,然后,我们可以看到如何控制它并分析GC日志以查找应用程序中发生的任何差异。

一、什么是自动垃圾收集?

自动垃圾收集是指对堆内存的查看,并识别哪些对象正在使用哪些对象,以及删除未使用的对象的过程。

首先我们看一下自动GC垃圾收集,它的步骤如下:

1.标记(Marking)

该过程的第一步称为标记。其实就是垃圾收集器识别哪些内存正在使用,哪些内存不在使用的地方。

如果必须扫描系统中的所有对象,将是一个非常耗时的过程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.正常删除(Normal Deletion)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正常删除是指移除未引用的对象,留下引用的对象和指向空闲空间的指针。

3.压缩删除(Deletion with Compacting)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

要进一步提高性能,除了删除未引用的对象外,还可以压缩剩余的引用对象。

通过将引用的对象移动到一起,这使得新的内存分配更加容易和快速。

二、全自动回收管理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当正在进行垃圾收集时,如果你的应用程序在该时间段内没有响应时,其实我们的期望是,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回收,清理和压缩该空间。

三、如何在Java中调整垃圾收集的优化参数呢?

垃圾收集是指当JVM不再需要对象时,需要将它回收,释放内存。它包括查找不再使用的对象,释放与这些对象关联的内存,并偶尔压缩堆以防止内存碎片。

垃圾收集器使用一个或多个线程来执行回收工作。一般来说,为了完成跟踪对象引用及在内存中移动对象的工作,它需要确保应用程序线程当前没有使用这些对象,如果应用程序线程正在使用对象,GC回收时会导致对象的内存位置发生变化,可能发生不可预测的事情。这就是垃圾收集器在执行某些任务时必须暂停所有应用程序线程的原因。这些暂停有时被称为Stop-The-World暂停(吊炸天,全世界都被停止,哈哈)。

3.1调整堆大小

垃圾收集调优的第一步是调整堆的大小。这是因为如果堆太小,则会发生太多的GC回收回收内存次数,这会降低整体应用程序吞吐量。如果堆太大,那么GC回收次数会更少,但GC需要很长的时间,那么你的系统响应时间指标会受到影响。并行收集器特别容易受到堆大小的影响,因此如果你需要大的堆并且暂停时间较短,那么你应该尝试使用G1GC收集器。

备注:自从Java 9和Shenandoah垃圾收集器被视为还处于“实验性”阶段,不推荐使用并发标记扫描(CMS)收集器。但如果你正在运行在线交互式应用程序,那么系统会默认选择G1GC收集器,如果你正在运行脱机批处理应用程序,那么并行收集器应该是你的首选,这是我给大家的建议。

堆的大小由两个值控制:使用ms标志指定的初始值和使用mx标志指定的最大值。

-Xms1g -Xmx8g

堆的初始大小和最大大小,可以由JVM根据工作负载自动调整堆大小。如果JVM遇到内存压力并且观察到GC执行次数过多,它会不断增加堆,直到内存压力消失为止,或直到堆达到其最大值为止。如果内存压力很低,JVM还可以通过缩小堆大小来决定减少暂停时间。这个过程称为自适应大小调整,它不仅可以调整堆的整体大小,还可以调整年轻代和老代的大小和比例。

当然,如果你想调整GC行为和大小,我建议你可以选择关闭自适应大小调整。这可以节省JVM,这是计算堆大小所需的一小段时间。你可以通过将标志设置UseAdaptiveSizePolicy为false 来执行此操作。

-XX:-UseAdaptiveSizePolicy

文末

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

小编将自己6年以来的面试经验和学习笔记都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。

其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
进步,一起学习。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值