作者:京东科技白杨前言:背景:为了应对618和双11大促,消费金融端会根据零售端大促的节奏进行整体系统准备。对核心流量入口承载的系统进行加固优化,消除系统风险,确保推广期间系统稳定性。大促期间,消费金融业务面临与用户面对面、高并发、系统风险大概率直接导致资金流失风险等问题。在日常压测和大促过程中,经常会出现JVM存在大量youngGC和部分fullGC,导致性能下降,可用性降低的情况。之前对Jvm的垃圾回收机制不是很熟悉,如何规避,如何调优,基本上什么都不懂,这篇文章也是对所学知识的巩固~1.什么是GC虚拟机?JVM(Java虚拟机)。JVM是Java程序的虚拟机,是实现Java语言的解释器。它提供了一个独立于操作系统的运行环境,使得Java程序可以在任何支持JVM的计算机上运行。JVM负责Java字节码的加载、校验、解释、执行和垃圾回收,为Java程序提供内存管理、线程管理、安全控制等服务。JVM中的GC(GarbageCollection)是garbagecollection的缩写,是JVM的内存管理机制。YoungGC和FullGC是两种不同的GC算法。YoungGC:新生代对象的回收算法,通常使用复制算法或标记算法。因为新生代中的对象生命周期短,所以YoungGC比FullGC快很多。FullGC:一种针对整个堆内存的回收算法,用于回收那些在YoungGC中没有回收的存活对象。FullGC比较慢,因为它需要扫描整个堆内存,所以对系统性能的影响比较大。因此,在设计Java应用程序时,需要尽量减少FullGC的次数,以保证系统性能。常用的方法有扩大新生代的内存空间,减少数组长度等。以上基本上就是对Jvm和Gc的一个大概的解释。但是可以很明显的看到少了一些细节,对我们来说还是没用的。考生应该如何理解具体的场景??我们先来了解一下youngGC的诞生过程:首先了解copy算法和markfinishing算法,这是两种不同的YoungGC回收算法。复制算法:将新生代内存分成大小相等的两部分。新创建的对象存储在一个部分,而另一部分用于存储存活的对象。当新生代内存不够时,就会发生YoungGC,将存活下来的对象复制到另一个内存区域。复制算法不会造成内存碎片,但会消耗一定的内存空间。标记排序算法:每次YoungGC时,首先标记所有存活的对象,然后将所有未存活的对象一起排序。因此,内存碎片会导致空间浪费。标记算法适用于需要保持内存空间整洁的应用程序,例如那些长时间运行的服务器应用程序。看看这个。本质上,YoungGc可以理解为jvm正常的垃圾清理过程。根据上面的解释,相信聪明的朋友可以清楚的看出,youngGc的回收效率更高,对业务端的影响更大。小多了~所以,我们来仔细看看这个让人头疼的fullGc,它是怎么来的?FullGC是FullGarbageCollection的缩写,指的是扫描整个堆内存,回收不用的对象,整理内存的过程。由于堆内存的整体回收过程非常缓慢,FullGC会导致应用程序暂停。上面说了,只有更合理的内存分配,避免未使用对象的频繁出现,调整堆内存的扫描时间。FullGC,全垃圾回收,是一种垃圾回收过程,暂停所有应用线程,回收整个堆。(这太可怕了。。。)初始标记:首先,垃圾收集器标记哪些对象需要被回收。并发标记:垃圾收集器然后将标记任务分发给多个线程,这些线程并发执行标记任务。重标记:在并发标记过程中,如果创建了新的对象,需要对这些对象进行重标记。整理:接下来,垃圾收集器将未标记的对象整理到内存的一端。回收:最后,垃圾收集器回收标记的对象并释放内存。放一张图给大家理解~FullGc的生命过程~本质上就是垃圾太多,无法正常工作,内存空间不够用。你必须停止一切并进行一般清洁。2.写代码Whatcanyoudowhen从上面可以看出,fullGc是非常可怕的,因为堆内存的整体回收过程非常缓慢,因此,FullGC可能会导致应用挂起,直接崩溃。..为了避免FullGC的发生,合理设置系统堆内存的大小和优化代码是必不可少的。基本上有以下技巧:?调整堆内存的大小:确定合适的堆内存大小,避免FullGCkey的发生。?代码的内存优化:使用不同的数据结构,避免内存泄漏,使用对象池和其他技术。?使用更大的新生代:新生代是一块内存区域,存放短命对象,更大的新生代可以降低FullGC的频率。?设置合适的垃圾回收算法:使用G1GC算法等技术可以提高系统性能并降低FullGC的频率。?这些是避免FullGC发生的一些常见建议。请注意,每种情况都不同,因此请根据您的情况选择合适的方法。这些方法看起来还是很抽象。。。举个具体的例子吧首先,堆内存的大小和垃圾回收算法都不是我们可以操作和关心的,业务方一般也不太擅长调整,所以就交给运维同学了。简单介绍,调整内存大小:通过调整JVM参数,如-Xms,-Xmx,适当增加内存。具体我们可以做什么,最重要的是减少数据对象的生命周期:通过使用引用弱引用、软引用、幻象引用等类型,当不需要数据对象时,可以直接回收数据对象,从而避免FullGC。缩短数据对象的生命周期,是指在程序中使用对象时,尽量缩短对象的生存时间。这样可以减少垃圾对象的数量,降低FullGC的频率。这是我们需要重点关注的!!以下是一些具体的例子:1.避免使用不必要的临时对象:如果程序中有大量的临时对象,它们可能很快就会被垃圾收集器清理掉。因此,你应该避免创建不必要的临时对象来减少对象的生命周期。例如:doubleaverage(double[]values){doublesum=0;for(doublevalue:values){sum+=value;}returnsum/values.length;}在这个例子中,数组values是一个临时对象,在函数结束时会被销毁。这样,您就不必考虑如何删除集合,避免了内存泄漏的风险。另外,Stringconcatenate(List
