java 内存回收参数_Java垃圾回收器以及内存日志分析

垃圾回收器

垃圾回收器(GarbageCollector),对象存在被引用称为活对象,而没有被引用的对象称为垃圾对象/垃圾内存,找到垃圾对象并回收是Collector的主要工作,该过程称为垃圾回收(Garbage

Collection)。

Collector的职责:分配内存,保证有引用的内存不被释放,回收没有指针引用的内存。

Hotspot提供三类垃圾回收器:串行回收器(SerialCollector),并行回收器(Parallel

Collector),并行标志扫描垃圾回收器(CMS,ConcurrentMarkSweep Collector),G1回收器(G1

Collector)。

串行回收器是JVM在client模式下默认的GC方式,可以通过JVM配置参数-XX:

UseSerialGC来指定GC使用该回收算法。串行回收器主要有两个特点:第一,它仅仅使用单线程进行垃圾回收;第二,它独占式的垃圾回收。在串行收集器进行垃圾回收时,Java

应用程序中的线程都需要暂停,等待垃圾回收的完成,这样给用户体验造成较差效果。虽然如此,串行回收器却是一个成熟、经过长时间生产环境考验的极为高效的回收器。

并行回收器只是简单地将串行回收器多线程化,Parallel

GC根据Minor GC和Full

GC的不同分为三种,分别是ParNewGC、ParallelGC和ParallelOldGC.

ParNewGC可以通过-XX:

UseParNewGC参数来指定。ParallelGC是JVM在server模式(在64位模式下的JVM和OS中,默认会使用-server参数)下默认的GC方式,可以同JVM配置参数-XX:

UseParallelGC参数来指定GC使用该回收算法。ParallelOldGC可以通过-XX:

UseParOldGC参数来指定。他们的并发回收的线程数可以通过-XX:ParallelGCThreads来指定。ParallelOldGC与ParallelGC的不同之处在于Full

GC,前者Full

GC进行的动作为清空整个Heap堆得垃圾对象,清楚Perm区中已经被卸载的类信息,并进行压缩。而后者是清楚Heap堆中的部分来及对象,并进行部分的空间压缩。

它的回收策略、算法以及参数和串行回收器一样。并行回收器也是独占式的回收器,在收集过程中,应用程序会全部暂停。但由于并行回收器使用多线程进行垃圾回收,因此,在并发能力比较强的

CPU 上,它产生的停顿时间要短于串行回收器,而在单 CPU

或者并发能力较弱的系统中,并行回收器的效果不会比串行回收器好,由于多线程的压力,它的实际表现很可能比串行回收器差。

CMS回收器,可通过-XX:

UseConcMarkSweepGC来指定,并发的默认线程数为4,也可通过ParallelCMSThreads来指定,与并行回收器不同,CMS

收集器主要关注于系统停顿时间。CMS 是 Concurrent Mark Sweep

的缩写,意为并发标记清除,从名称上可以得知,它使用的是标记-清除算法,同时它又是一个使用多线程并发回收的垃圾回收器。

CMS工作的主要步骤有

①CMS-initial-mark,单线程处理环节,并且会完全暂停JVM,找到所有的root根对象(栈中引用的对象,本地方法栈中引用的对象,常量引用的对象),将root根所引用的对象标志在一个在一个bitmap钟,此时业务恢复正常运行,CMS进入下一步骤

②CMS-concurrent-mark,根据第1个步骤对记录在Bitmap中的信息进行并发标志对象,此时JVM内所运行的程序不会暂停。

③CMS-concurrent-preclean,处理young与old之间的引用,尽量将可能的引用梳理出来,节约remark的时间

④CMS-consurrent-abortable-preclean

⑤CMS-remark,JVM全暂停的第2个阶段,由于全面几个步骤中存在的业务并发导致一些赞数据,remark解决了这个问题,因此这个阶段也会全部暂停,但是它不是从root开始遍历,而是根据一个卡表(卡表中有脏数据的信息)。

⑥CMS-concurrent-sweep,不停机,单线程操作,按照内存的地址顺序遍历old、perm区域,根据Bitmap中的记录,对垃圾内存进行清除操作。

⑦CMS-consurrent-reset

CMS 回收器在其主要的工作阶段虽然没有暴力地彻底暂停应用程序线程,但是由于它和应用程序线程并发执行,相互抢占

CPU,所以在 CMS 执行期内对应用程序吞吐量造成一定影响。CMS 默认启动的线程数是

(ParallelGCThreads 3)/4),ParallelGCThreads

是新生代并行收集器的线程数,也可以通过-XX:ParallelCMSThreads 参数手工设定 CMS 的线程数量。当

CPU

资源比较紧张时,受到 CMS 收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕。

由于 CMS 回收器不是独占式的回收器,在 CMS

回收过程中,应用程序仍然在不停地工作。在应用程序工作过程中,又会不断地产生垃圾。这些新生成的垃圾在当前 CMS

回收过程中是无法清除的。同时,因为应用程序没有中断,所以在 CMS

回收过程中,还应该确保应用程序有足够的内存可用。因此,CMS

回收器不会等待堆内存饱和时才进行垃圾回收,而是当前堆内存使用率达到某一阈值时,便开始进行回收,以确保应用程序在 CMS

工作过程中依然有足够的空间支持应用程序运行。

这个回收阈值可以使用-XX:CMSInitiatingOccupancyFraction 来指定,默认是

68。即当老年代的空间使用率达到 68%时,会执行一次 CMS 回收。如果应用程序的内存使用率增长很快,在 CMS

的执行过程中,已经出现了内存不足的情况,此时,CMS 回收将会失败,JVM

将启动串行回收器进行垃圾回收。如果这样,应用程序将完全中断,直到垃圾回收完成,这时,应用程序的停顿时间可能很长。因此,根据应用程序的特点,可以对-XX:CMSInitiatingOccupancyFraction

进行调优。如果内存增长缓慢,则可以设置一个稍大的值,大的阈值可以有效降低 CMS

的触发频率,减少老年代回收的次数可以较为明显地改善应用程序性能。反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发串行回收器。

G1回收器在Hotspot上只算是一个雏形,适用于堆内存很大的情况,通过JVM参数 –XX: UseG1GC

使用G1垃圾回收器。G1的基本思想是将Java堆划分为多个相对较小且大小想用的内存板块,这些板块我们叫做region。它也有分代啊,在region里分代,在运行过程中会维护一个优先级列表,这个优先级列表其实是按照垃圾多少来排序的,这样垃圾最多的region就是最前面的一个板块,每次就回收垃圾最多的板块。

a4c26d1e5885305701be709a3d33442f.png

Java内存日志分析

我们不知道什么时候回发生内存泄漏,但是我们可以在JVM启动时加上一些参数进行控制,当JVM出现问题的时候可以记录下当时的情况,还有记录下来的GC的日志。

GC的输出配置参数如下:

-verbose:gc,可以辅助输出一些详细的GC信息。

-XX:

PrintGCDetails,输出GC的详细信息。

-XX:

PrintGCApplicationStoppedTime,输出GC造成应用程序暂停的时间。

-XX:

PrintGCDateStamps,GC发生的时间信息

-XX:

PrintHeapAtGC,在GC前后输出堆中各个区域的大小

-Xloggc:[file],将GC信息输出到单独的文件中

除了CMS的日志与其他GC的日志差别较大外,每种GC的日志形式都可以抽象成如下格式:

[GC [:->(total size1), secs]

->(total size2), secs]

q其中说明如下:

,表示收集器的名称。

,表示young区在GC前占用的内存。

,表示young区在GC后占用的内存。

,表示young区局部收集时JVM暂停处理的时间。

,表示JVM

Heap在GC前占用的内存。

<

style="line-height: 21px; text-indent:

2em;">ending occupancy2>,表示JVM Heap在GC后占用的内存

,表示GC过程中JVM暂停处理的总时间。

可以根据日志来判断是否有内存泄漏,如果

-

=<

ending

occupancy2>

-,表明这次GC对象100%倍回收,没有对象进入Old区或者Perm区。如果等号前面的值大于等号后面的值,那么差值就是这次回收对象进入Old区或者是Perm区的大小。如果随着时间的演唱,<ending

occupancy2>的值一直在增加,而且Full

GC很频繁,那么很可能就是内存泄漏。

除去日志文件分析外,还可以直接通过JVM自带的一些工具分析,如jstat,使用命令jstat -gcutil [pid]

[internal] [count],结果如下:a4c26d1e5885305701be709a3d33442f.png

在上面日志中的参数含义如下:

S0表示Heap上的Survivor space 0区已使用空间的百分比。

S1表示Heap上的Survivor space 1区已使用空间的百分比。

E表示Heap上的Eden

space区已使用空间的百分比。

O表示Heap上的Old

space区已使用空间的百分比。

M表示元数据区已使用空间的百分比。

CCS表示压缩使用比例。

YGC表示应用从应用程序启动到采样时发生Young GC的次数

YGCT表示从应用程序启动到采样时Young GC所用的时间(秒)

FGC表示从应用程序启动到采样时Full GC的次数。

FGCT表示从应用程序启动到采样时Full GC所用的时间(秒)

GCT表示从应用程序启动到采样时用于垃圾回收的总时间(秒)

除此之外,还可以使用堆快照文件分析,可通过命令jmap -dump:format=b,file=[filename]

[pid]来记录下堆得内存快照,然后利用第三方工具(mat)来分析整个Heap的情况。如果内存耗尽那么可能导致JVM直接垮掉,可以通过参数:-XX:

HeapDumpOnOutOfMemoryError来配置当内存耗尽时记录下内存快照。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值