Java 如何看 GC 日志

如果你的电脑用久了,会因为后台偷偷开了好多程序而变卡,甚至弹出“内存不足”的提示,这就像咱们的Java程序运行时,也会在后台悄悄处理各种数据,用完后没及时清理的话,就会出问题。而GC(垃圾回收)日志,就是Java程序给我们的“后台运行日记”,能帮我们找出“内存变卡”的原因。

要想看懂GC日志,第一步得先把“日记”打开——也就是开启GC日志的生成功能,不然程序不会自动记录。不同的Java版本,开启的方法有点不一样,就像不同牌子的笔记本,开机按钮位置不同一样。比如常用的Java 8版本,我们只需要在启动程序的命令里,加上-Xloggc:gc.log就行,它会在程序运行的文件夹里生成一个叫“gc.log”的文件,所有GC的过程都会写在里面。要是用更新的Java 9及以上版本,方法会更灵活,不过核心还是要让程序把GC的过程记下来,不然就没东西可看了。

Java 如何看 GC 日志

拿到GC日志文件后,接下来就是找里面的关键信息。日志里的内容看起来乱糟糟的,其实每一段都像一段“小剧情”,咱们找两个最常见的片段就行。第一个是“年轻代回收”的内容,年轻代就像程序的“临时储物箱”,用来放刚创建的小对象,用完就丢。比如你用手机拍了张临时照片,看完就关,存在“临时相册”里,这个“临时相册”就相当于年轻代。日志里会写类似“123.456: [GC (Allocation Failure) …… 100M->20M(200M)]”的内容,这里的“100M”是回收前年轻代用了100兆内存,“20M”是回收后剩20兆,括号里的“200M”是年轻代总大小。要是回收后剩下的内存太少,比如只剩几兆,那下次临时照片存不下,就会触发更费劲的“老年代回收”,就像临时相册满了,得把不用的照片移去“永久相册”(老年代)。

还有一个关键片段是“老年代回收”,老年代是程序的“永久储物箱”,放那些长期用的大对象,就像你存在手机相册里的旅行照片,不会随便删。日志里的老年代回收片段会写类似“125.678: [Full GC (Ergonomics) …… 150M->50M(500M)]”,这里的“Full GC”就是老年代回收,比年轻代回收费时间。要是经常出现Full GC,比如每隔几分钟就来一次,那程序就会经常卡顿,就像手机每隔几分钟就要整理一次相册,没法好好用。

除了这两个片段,还要看GC的“耗时”。日志里会有类似“User time 0.05, Sys time 0.02, Real time 0.1”的内容,这里的“Real time”就是GC实际花的时间,要是这个时间超过1秒,对于需要流畅运行的程序(比如购物APP)来说,用户就会感觉到卡顿。就像你等手机整理相册等了1秒,会觉得有点卡,要是等了5秒,就会直接退出了。

举个生活化的例子,你开了个外卖软件,突然弹出“加载慢”,这时候打开GC日志,发现年轻代每次回收后都只剩10兆,老年代回收又经常出现,还每次花2秒,那大概率是程序里有好多临时的外卖地址、订单数据没及时清理,导致内存不够,GC频繁工作。这时候要么给程序加个“更大的储物箱”(调整内存参数),要么改改代码,让没用的数据用完就删,就像不用的外卖订单及时删掉,给临时相册腾空间。

最后要注意,GC日志不是看的片段越多越好,重点看“回收后内存是否够用”和“耗时是否太长”这两个问题,就像看手机卡顿原因,不用纠结每个后台程序的细节,只要找到哪个程序占内存多、哪个程序耗电快就行,这样就能轻松解决问题了。

上一篇 Swift 编程语言核心特性与常见应用场景知识科普