一、基本收集算法
1. 复制:将堆内分成两个相同空间,从根(ThreadLocal的对象,静态对象)开始访问每一个关联的活跃对象,将空间A的活跃对象全部复制到空间B,然后一次性回收整个空间A。
因为只访问活跃对象,将所有活动对象复制走之后就清空整个空间,不用去访问死对象,所以遍历空间的成本较小,但需要巨大的复制成本和较多的内存。
优点:只访问活跃对象,遍历快
缺点:需要内存比较多,浪费一部分内存,不适合年老代
2. 标记清除(mark-sweep):收集器先从根开始访问所有活跃对象,标记为活跃对象。然后再遍历一次整个内存区域,把所有没有标记活跃的对象进行回收处理。该算法遍历整个空间的成本较大暂停时间随空间大小线性增大,而且整理后堆里的碎片很多。
优点:不浪费内存
缺点:遍历2次,2次标记效率都不高,内存碎片多
3. 标记整理(mark-sweep-compact):综合了上述两者的做法和优点,先标记活跃对象,然后将其合并成较大的内存块。
移动了活跃对象,回收后留下完整内存块
二 JVM GC收集器
1.Serial收集器-XX:+UseSerialGC 复制收集算法
单线程收集器,收集时会暂停所有工作线程(我们将这件事情称之为Stop The World,下称STW),使用复制收集算法,虚拟机运行在Client模式时的默认新生代收集器。
2.ParNew收集器-XX:+UseParNewGC 复制收集算法 多线程执行
ParNew收集器就是Serial的多线程版本,除了使用多条收集线程外,其余行为包括算法、STW、对象分配规则、回收策略等都与Serial收集器一摸一样。对应的这种收集器是虚拟机运行在Server模式的默认新生代收集器,在单CPU的环境中,ParNew收集器并不会比Serial收集器有更好的效果。
3.Parallel Scavenge收集器-XX:+UseParallelGC 复制算法,吞吐量最大化
Parallel Scavenge收集器(下称PS收集器)也是一个多线程收集器,也是使用复制算法,但它的对象分配规则与回收策略都与ParNew收集器有所不同,它是以吞吐量最大化(即GC时间占总运行时间最小)为目标的收集器实现,它允许较长时间的STW换取总吞吐量最大化。
4.Serial Old收集器-XX:+UseSerialGC 标记整理算法
Serial Old是单线程收集器,使用标记-整理算法,是老年代的收集器,上面三种都是使用在新生代收集器。
5.Parallel Old收集器-XX:+UseParallelOldGC 标记整理算法多线程执行
老年代版本吞吐量优先收集器,使用多线程和标记-整理算法,JVM 1.6提供,在此之前,新生代使用了PS收集器的话,老年代除Serial Old外别无选择,因为PS无法与CMS收集器配合工作。
6.CMS(Concurrent Mark Sweep)收集器XX:+UseconcMarkSweepGC 标记,置换 不压缩 算法
压缩需要加参数-XX:CMSFullGCsBeforeCompaction(多少次FullGC后压缩内存) 或者-XX+UseCMSCompactAtFullCollection(CMS后压缩内存)
CMS收集器使用的是标记-清除算法,也就是说它在运行期间会产生空间碎片,所以虚拟机提供了参数开启CMS收集结束后再进行一次内存压缩。
CMS大体过程为:
(1)并发gc会先暂停jvm运行,然后标志应用中的强可达对象;init-mark,stop the world
(2)开始并发标志引用强可达对象的对象;这时程序还在运行,concurrent-mark
(3)因为程序正在运行,这时重新标志一下引用被修改的对象(这时jvm会再次暂停)rescan
(4)重新标记后,堆中所有活动对象被标记出来了,然后开发开始回收堆中的垃圾对象;sweep
(5)该算法不进行compact,而是在内存中建立一个空闲内存的链表,下次在old区分配空间时,会先找到一个符合条件的空闲空间给对象,该方式会影响old区和young区的对象空间分配,影响young区主要是由于有些young区的对象需要转至old区.
三、JVM设置需要注意的地方
1.-Xmn 与-XX:NewRatio 不要同时设置
2.-Xss一定要设置,JDK5.0以后每个线程堆栈大小为1M,对一般的应用来说,256K足够了,如果发生StackOverFlow错误,那么加大这个值也没用。
jvm 栈 和本地方法栈可能存在的异常:
StackOverFlowError:线程请求的栈深度>虚拟机所允许的深度
OutOfMemory:当扩展时无法申请到足够的内存(大部分虚拟机都允许动态扩展,java虚拟机规范也允许固定长度)
3.设置-XX:+DisableExplicitGC,避免RMI或应用显示调用System.gc().如果有此类调用gc日志中会含有System标志。
修正:
1.jdk6 u32之前存在一个bug,某些情况下,cms GC 不回收Dirent byte buffer,堆外内存。
2.使用这个参数可能会导致cms GC触发之前,堆外内存过大时,物理内存或地址空间不足,出现OOM错误。
因此建议:
1.不使用这个参数,改为:-XX:+ExplicitGCInvokesConcurrent
2.配置堆外内存最大空间:-XX:MaxDirectMemorySize。不配置时,默认与-Xmx值相同。可能造成OOM.
4.-XX:MaxTenuringThreshold 对象最多!经过多少次minor GC后进入年老代。设置为0,则不经过survior拷贝,直接进入年老代。增大此值会增加对象在Minor GC被回收的几率,减小此值会增加对象进入年老代的几率。注意最多,有可能不经过那么多次,比如
4.1.大的数组对象,如果在survivor空间中相同年龄所有对象大小的累计值大于survivor空间的一半,大于或等于个年龄的对象就可以直接进入老年代,无需达到MaxTenuringThreshold中要求的年龄
4.2.配置了-XX:PretenureSizeThreshold 参数,则大于指定byte的对象直接进入年老代分配。
5.持久代GC时回收无引用的废弃常量与无用类。无用类需满足以下三个条件:
5.1.该类所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例。
5.2.加载该类的ClassLoader已经被GC。
5.3.该类对应的java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该类的方法。
是否对类进行回收可使用-XX:+ClassUnloading参数进行控制,还可以使用-verbose:class或者-XX:+TraceClassLoading、-XX:+TraceClassUnLoading查看类加载、卸载信息。
在大量使用反射、动态代理、CGLib等bytecode框架、动态生成JSP以及OSGi这类频繁自定义ClassLoader的场景都需要JVM具备类卸载的支持以保证永久代不会溢出
6 -XX:CMSInitiatingOccupancyFraction=70以上 堆内存达到多少比例时,触发CMS。需要与-XX:+UseCMSInitiatingOccupancyOnly 同时使用以保证CMS不自动触发,否则不到比例也可能触发CMS.
计算公式一:CMSInitiatingOccupancyFraction <=((Xmx-Xmn)-(Xmn-Xmn/(SurvivorRatior+2)))/(Xmx-Xmn)*100
考虑了2个救助区中一个servior不会使用的情况。
计算公式二:(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn
统一考虑年轻代。
满足以上2个计算公式,则不会出现 concurrent model fail。及不会出现并行回收失败,降级为虚拟机串行回收(SerialGC)的情况。
7.CMS碎片问题
因为年老代的并发收集器使用标记,清除算法,所以不会对堆进行压缩.当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象.但是,当堆空间较小时,运行一段时间以后,就会出现"碎片",如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记,清除方式进行回收.如果出现"碎片",可能需要进行如下配置:
-XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩.
-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩
8.XMX和XMS设置一样大,MaxPermSize和MinPermSize设置一样大,这样可以减轻伸缩堆大小带来的压力,还真有人不这么干
9:promotion failed:
救助空间不足,要放到老生代,但老生代空闲空间存在碎片,导致没有足够大的连续空间来存放新生代对象的升级时,机会触发promotion failed
解决方法:
9.1.增大救助空间、增大年老代
增大救助空间就是调小-XX:SurvivorRatio这个参数是Eden区和Survivor区的大小比值,默认是32
增大年老代,调大-Xmn参数,增加新生代,或调大-XX:NewRatio,减少新生代比例,增大年老代。
9.2..去掉救助空间(不赞成)
调大-XX:SurvivorRatio到非常大的数值65536
10:Concurrent Mode Failure
并发收集器在应用运行时进行收集,所以需要保证堆在垃圾回收的这段时间有足够的空间供程序使用,否则,垃圾回收还未完成,堆空间先满了。这种情况下将会发生“并发模式失败”,此时整个应用将会暂停,进行垃圾回收
解决方法:
10.1.满足第6点的公式,可以避免这个问题。
10.2.调小CMSMaxAbortablePrecleanTime的值 尽快回收
11.CMS默认启动的回收线程数目是(ParallelGCThreads + 3)/4)
也可以通过:-XX:ParallelCMSThreads=20 设置
12.为了减少CMS GC第二次暂停的时间,开启并行remark:-XX:+CMSParallelRemarkEnabled。如果remark还是过长的话,可以开启-XX:+CMSScavengeBeforeRemark选项,强制remark之前开始一次minor gc,减少remark的暂停时间,但是在remark之后也将立即开始又一次minor gc。
13.+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled CMS回收持久代
14.FullGC的触发条件
14.1.old空间不足 达到比例(CMSInitiatingOccupancyFraction) 或 promotion failed 或 current mode failed(这个会很悲剧)
14.2.Perm空间不足 92%
14.3.显示调用System.GC, RMI等的定时触发
14.4.YGC时的悲观策略
14.5.dump live的内存信息时(jmap –dump:live)
15。YGC时的悲观策略
15.1、在YGC执行前,min(目前新生代已使用的大小,之前平均晋升到old的大小中的较小值) > 旧生代剩余空间大小 ? 不执行YGC,直接执行Full GC: 执行YGC;15.2、在YGC执行后,平均晋升到old的大小 > 旧生代剩余空间大小 ? 触发Full GC : 什么都不做
CMSGc时,旧生代剩余空间需要考虑CMSInitiatingOccupancyFraction
在Minor GC触发时,会检测之前每次晋升到老年代的平均大小是否大于老年代的剩余空间,如果大于,改为直接进行一次Full GC,如果小于则查看HandlePromotionFailure设置看看是否允许担保失败,如果允许,那仍然进行Minor GC,如果不允许,则也要改为进行一次Full GC
16.导致OOM的原因
1.GC overhead limit exceeded
2.Java Heap Space
3.Unable to create new native thread
4.PermGen Space
5.Direct buffer memory
6.request {} bytes for {}. Out of swap space?
四 案例及日志
CMS GC的一个具体案例:
具体过程为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
2013 - 11 -27T04: 00 : 12.819 + 0800 : 38892.743 : [GC [ 1 CMS-initial-mark: 1547313K(2146304K)] 1734957K(4023680K), 0.1390860 secs] [Times: user= 0.14 sys= 0.00 , real= 0.14 secs] 2013 - 11 -27T04: 00 : 12.958 + 0800 : 38892.883 : [CMS-concurrent-mark-start] 2013 - 11 -27T04: 00 : 19.231 + 0800 : 38899.155 : [CMS-concurrent-mark: 6.255 / 6.272 secs] [Times: user= 8.49 sys= 1.57 , real= 6.27 secs] 2013 - 11 -27T04: 00 : 19.231 + 0800 : 38899.155 : [CMS-concurrent-preclean-start] 2013 - 11 -27T04: 00 : 19.250 + 0800 : 38899.175 : [CMS-concurrent-preclean: 0.018 / 0.019 secs] [Times: user= 0.02 sys= 0.00 , real= 0.02 secs] 2013 - 11 -27T04: 00 : 19.250 + 0800 : 38899.175 : [CMS-concurrent-abortable-preclean-start]
CMS: abort preclean due to time 2013 - 11 -27T04: 00 : 25.252 + 0800 : 38905.176 : [CMS-concurrent-abortable-preclean: 5.993 / 6.002 secs] [Times: user= 6.97 sys= 2.16 , real= 6.00 secs] 2013 - 11 -27T04: 00 : 25.253 + 0800 : 38905.177 : [GC[YG occupancy: 573705 K ( 1877376 K)] 38905.177 : [Rescan (parallel) , 0.3685690 secs] 38905.546 : [weak refs processing, 0.0024100 secs] 38905.548 : [cla ss unloading, 0.0177600 secs] 38905.566 : [scrub symbol & string tables, 0.0154090 secs] [ 1 CMS-remark: 1547313K(2146304K)] 2121018K(4023680K), 0.4229380 secs] [Times: user= 1.41 sys= 0.01 , real= 0.43 secs] 2013 - 11 -27T04: 00 : 25.676 + 0800 : 38905.601 : [CMS-concurrent-sweep-start] 2013 - 11 -27T04: 00 : 26.436 + 0800 : 38906.360 : [CMS-concurrent-sweep: 0.759 / 0.760 secs] [Times: user= 1.06 sys= 0.48 , real= 0.76 secs] 2013 - 11 -27T04: 00 : 26.436 + 0800 : 38906.360 : [CMS-concurrent-reset-start] 2013 - 11 -27T04: 00 : 26.441 + 0800 : 38906.365 : [CMS-concurrent-reset: 0.005 / 0.005 secs] [Times: user= 0.00 sys= 0.00 , real= 0.00 secs] 这个是一个正常的CMS的日志,共分为七个步骤,重点关注initial-mark和remark这两个阶段,因为这两个是停机的。 A、[GC [1 CMS-initial-mark: 1547313K(2146304K)] 1734957K(4023680K), 0.1390860 secs] [Times: user=0.14 sys=0.00, real=0.14 secs] 各个数据依次表示标记前后old区的所有对象占内存大小和old的capacity,整个JavaHeap(不包括perm)所有对象占内存总的大小和JavaHeap的capacity。 B、2013-11-27T04:00:25.253+0800: 38905.177: [GC[YG occupancy: 573705 K (1877376 K)]38905.177: [Rescan (parallel) , 0.3685690 secs]38905.546: [weak refs processing, 0.0024100 secs]38905.548: [class unloading, 0.0177600 secs]38905.566: [scrub symbol & string tables, 0.0154090 secs] [1 CMS-remark: 1547313K(2146304K)] 2121018K(4023680K), 0.4229380 secs] [Times: user=1.41 sys=0.01, real=0.43 secs] Rescan (parallel)表示的是多线程处理young区和多线程扫描old+perm的卡表的总时间, parallel 表示多GC线程并行。 weak refs processing 处理old区的弱引用的总时间,用于回收native memory。 class unloading 回收SystemDictionary消耗的总时间 |
a)首先jvm根据-XX:CMSInitiatingOccupancyFraction,-XX:+UseCMSInitiatingOccupancyOnly 来决定什么时间开始垃圾收集
b)如果设置了-XX:+UseCMSInitiatingOccupancyOnly,那么只有当old代占用确实达到了 -XX:CMSInitiatingOccupancyFraction参数所设定的比例时才会触发cms gc
c)如果没有设置-XX:+UseCMSInitiatingOccupancyOnly,那么系统会根据统计数据自行决定什么时候 触发cms gc;因此有时会遇到设置了80%比例才cms gc,但是50%时就已经触发了,就是因为这个参数 没有设置的原因
d)当cms gc开始时,首先的阶段是CMS-initial-mark,此阶段是初始标记阶段,是stop the world阶段, 因此此阶段标记的对象只是从root集最直接可达的对象
CMS-initial-mark:961330K(1572864K),指标记时,old代的已用空间和总空间
e)下一个阶段是CMS-concurrent-mark,此阶段是和应用线程并发执行的,所谓并发收集器指的就是这个, 主要作用是标记可达的对象
此阶段会打印2条日志:CMS-concurrent-mark-start,CMS-concurrent-mark
f)下一个阶段是CMS-concurrent-preclean,此阶段主要是进行一些预清理,因为标记和应用线程是并发执行的, 因此会有些对象的状态在标记后会改变,此阶段正是解决这个问题
因为之后的Rescan阶段也会stop the world,为了使暂停的时间尽可能的小,也需要preclean阶段先做一部分 工作以节省时间
此阶段会打印2条日志:CMS-concurrent-preclean-start,CMS-concurrent-preclean
g)下一阶段是CMS-concurrent-abortable-preclean阶段,加入此阶段的目的是使cms gc更加可控一些, 作用也是执行一些预清理,以减少Rescan阶段造成应用暂停的时间
此阶段涉及几个参数:
-XX:CMSMaxAbortablePrecleanTime:当abortable-preclean阶段执行达到这个时间时才会结束
-XX:CMSScheduleRemarkEdenSizeThreshold(默认2m):控制abortable-preclean阶段什么时候开始执行,即当eden使用达到此值时,才会开始abortable-preclean阶段
-XX:CMSScheduleRemarkEdenPenetratio(默认50%):控制abortable-preclean阶段什么时候结束执行
此阶段会打印一些日志如下:
CMS-concurrent-abortable-preclean-start,CMS-concurrent-abortable-preclean,CMS:abort preclean due to time XXX
h)再下一个阶段是第二个stop the world阶段了,即Remark阶段,此阶段暂停应用线程,对对象进行重新扫描并 标记
YG occupancy:964861K(2403008K),指执行时young代的情况
CMS remark:961330K(1572864K),指执行时old代的情况
此外,还打印出了弱引用处理、类卸载等过程的耗时
i)再下一个阶段是CMS-concurrent-sweep,进行并发的垃圾清理
j)最后是CMS-concurrent-reset,为下一次cms gc重置相关数据结构
一些日志:
、promotion failed的一段日志
1
2
|
2013 - 11 -27T03: 00 : 53.638 + 0800 : 35333.562 : [GC 35333.562 : [ParNew (promotion failed): 1877376K->1877376K(1877376K), 15.7989680 secs] 35349.361 : [CMS: 2144171K->2129287K(2146304K), 10.4200280 sec s] 3514052K->2129287K(4023680K), [CMS Perm : 119979K->118652K(190132K)], 26.2193500 secs] [Times: user= 30.35 sys= 5.19 , real= 26.22 secs] |
解释如下:
1
2
3
4
5
|
1877376K->1877376K(1877376K), 15.7989680 secs young区 2144171K->2129287K(2146304K), 10.4200280 sec old区情况 3514052K->2129287K(4023680K) heap区情况 119979K->118652K(190132K)], 26.2193500 secs perm区情况 [Times: user= 30.35 sys= 5.19 , real= 26.22 secs] 整个过程的时间消耗 |
一段正常的Young GC的日志
1
2
|
2013 - 11 -27T04: 00 : 07.345 + 0800 : 38887.270 : [GC 38887.270 : [ParNew: 1791076K->170624K(1877376K), 0.2324440 secs] 2988366K->1413629K(4023680K), 0.2326470 secs] [Times: user= 0.80 sys= 0.00 , real= 0 . 23 secs] |
ParNew这个表明是并行的回收方式,具体的分别是young区、整个heap区的情况;
一段通过system.gc产生的FullGC日志
1
|
2013 - 07 -21T17: 44 : 01.554 + 0800 : 50.568 : [Full GC (System) 50.568 : [CMS: 943772K->220K(2596864K), 2.3424070 secs] 1477000K->220K(4061184K), [CMS Perm : 3361K->3361K(98304K)], 2.3425410 secs] [Times: user= 2.33 sys= 0.01 , real= 2.34 secs] |
解释如下:
Full GC (System)意味着这是个system.gc调用产生的MSC。
“943772K->220K(2596864K), 2.3424070 secs”表示:这次MSC前后old区内总对象大小,old的capacity及这次MSC耗时。
“1477000K->220K(4061184K)”表示:这次MSC前后JavaHeap内总对象大小,JavaHeap的capacity。
“3361K->3361K(98304K)], 2.3425410 secs”表示:这次MSC前后Perm区内总对象大小,Perm区的capacity。
一个特殊的GC日志,根据动态计算直接进行的FullGC(CMS的方式)悲观策略
1
|
2013 - 03 -13T13: 48 : 06.349 + 0800 : 7.092 : [GC 7.092 : [ParNew: 471872K->471872K(471872K), 0.0000420 secs] 7.092 : [CMS: 366666K->524287K(524288K), 27.0023450 secs] 838538K->829914K(996160K), [CMS Perm : 3196K->3195K(131072K)], 27.0025170 secs] |
ParNew的时间特别短,jvm在minor gc前会首先确认old是不是足够大,如果不够大,这次young gc直接返回,进行MSC。
参考文档:
http://hi.baidu.com/576699909/item/9daf4d7c33a09f316f29f66c
http://www.viluo.com/post/25
http://blog.csdn.net/fycghy0803/article/details/6679827
http://www.cnblogs.com/redcreen/archive/2011/05/04/2037029.html
http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html#CMSInitiatingOccupancyFraction_value
http://blog.csdn.net/jiasanshou/article/details/24908567
http://blog.csdn.net/jiasanshou/article/details/24908371
http://blog.csdn.net/jiasanshou/article/details/24908187
http://blog.csdn.net/calvinxiu/article/details/1614473
http://guoliangqi.iteye.com/blog/630692
http://www.blogjava.net/BlueDavy/archive/2009/10/09/297562.html
http://www.iteye.com/topic/473874
http://hllvm.group.iteye.com/group/wiki/2870-JVM
http://ee.riaos.com/?p=20009582
相关推荐
JVM与GC调优课程视频 〖课程介绍〗: JVM与GC调优课程视频 〖课程目录〗: 1.笔记/ ├── 第1篇-字节码篇.png?x-oss-process=style/pnp8 ├── 第2篇-类的加载篇.png?x-oss-process=style/pnp8 ├── 第3篇-运行时...
JVM性能调优总结 JVM性能调优是Java开发中非常重要的一方面,直接影响到系统的性能和稳定性。本文将总结JVM性能调优的经验和技巧,并提供一些实用的配置参数和建议。 一、堆大小设置 堆大小是JVM性能调优中的一个...
"用于测试jvm gc调优-share-jvm-gc.zip"这个压缩包文件很可能包含了一些工具、脚本或教程,用于帮助我们了解和实践JVM的垃圾收集优化。 首先,我们需要理解JVM GC的基本原理。垃圾收集器的主要任务是识别并回收不再...
**JVM体系结构与GC调优** Java虚拟机(JVM)是Java应用程序的核心组成部分,它为Java程序提供了一个运行时环境。理解JVM的体系结构对于优化Java应用的性能至关重要,尤其是垃圾收集(Garbage Collection, GC)的...
### JVM_GC调优详解 #### 一、JVM体系结构概览 Java虚拟机(JVM)作为Java程序的运行环境,其内部结构复杂且高效。为了更好地理解JVM_GC调优,我们首先来了解一下JVM的基本组成部分。 1. **类装载器子系统(Class ...
### JVM_GC_调优总结 #### 一、GC(Garbage Collection)概述 **1.1 GC的概念** - **定义**: GC(Garbage Collection),即垃圾收集器,用于跟踪内存中的对象,并自动回收那些不再被其他对象引用的对象,释放这...
### 个人总结之—JVM性能调优实战 #### 概述 本文档是一篇关于JVM(Java虚拟机)性能调优的经典实战总结。在实际应用开发与维护过程中,JVM性能调优是一个非常重要的话题,它直接关系到应用程序运行效率、资源利用...
JVM 内存的系统级的调优主要的目的是减少 GC 的频率和 Full GC 的次数,过多的 GC 和 Full GC 是会占用很多的系统资源(主要是 CPU),影响系统的吞吐量。特别要关注 Full GC,因为它会对整个堆进行整理,导致 Full ...
JVM体系结构与GC调优总结,很详尽,面试必备呀,值得拥有!
大厂架构师-日均百万订单量的JVM优化与高级GC调优策略实战(5.8G) 〖课程介绍〗: 来自顶尖大厂的架构师级JVM优化与GC调优策略实战课程,是具备有尖端技术的优化课程。在课程内容上几乎不用过多的介绍,单是查阅目录就...
在深入讨论JVM(Java虚拟机)调优之前,我们有必要先了解一下虚拟机的基本概念和堆栈...通过上述的分析和总结,我们可以得出,JVM调优是一个涉及多方面知识的复杂过程,需要开发者具备扎实的理论基础和丰富的实践经验。
常见的GC调优策略包括: 1. 选择合适的GC算法:如Parallel、Concurrent Mark Sweep (CMS)、G1、ZGC或Shenandoah等。 2. 调整新生代和老年代的大小,避免Full GC频繁发生。 3. 使用CMS或G1等并发收集器,减少应用...
《JVM和GC详解及调优》是一本深入解析Java虚拟机(JVM)和垃圾收集(Garbage Collection,简称GC)的专业...对于团队负责人或系统架构师而言,理解JVM和GC调优也是必不可少的技能,有助于提升整个系统的稳定性和效率。
垃圾回收(GC)作为JVM的重要组成部分,其效率直接影响到程序的响应时间和资源利用率。本文旨在通过对JVM调优的基础概念和常见的垃圾回收算法进行深入剖析,帮助读者更好地理解和掌握JVM调优的关键技术。 #### 二、...
JVM参数调优是优化Java应用程序性能的关键环节,尤其是在服务器端的应用中,如Web服务器Resin。本实践案例中,作者分别尝试了三种不同的垃圾回收(GC)策略:串行回收、并行回收和并发回收,并针对每种策略提供了...
GC调优主要是对JVM的垃圾回收机制进行调整,以确保内存的有效利用和避免系统出现长时间的暂停。垃圾回收是JVM自动管理内存的过程,其目标是回收不再使用的对象所占用的内存空间。主要涉及以下几个方面: 1. **垃圾...
JVM性能调优是Java开发者应该掌握的重要技能,以下是JVM性能调优的知识点总结: JVM基础知识 * 虚拟机:是一种软件,执行虚拟计算机指令,分为系统虚拟机和程序虚拟机。Java虚拟机是程序虚拟机,专门为执行单个...
【标题】: "第04章 大促高并发系统下JVM如何调优指导03.pdf" 在大型促销活动期间,高并发系统的性能优化至关重要,尤其是Java虚拟机(JVM)的调优,它直接影响应用程序的响应速度和稳定性。本章节主要探讨了在亿级...
总结来说,JVM性能调优中的垃圾回收(GC)和内存管理是确保Java应用高效运行的关键。了解Java对象引用类型、垃圾回收算法以及分代处理垃圾的概念是进行JVM性能调优的基础。这些知识点对于准备Java面试的开发者来说,...