Gold and three silver four -JVM [series] CMS collector GC log analysis and positioning problems Detailed

beginning:

2B brother today to share with you a hard goods, why? Because there are two good things:

First, upgrade the LV2 brother ha ha times cool mood.

image

Second, to get the company of 2 thousand shares

image

In the company for two years, and finally become good brothers of the East Columbia.

image

CMS collector combat:

Combat began, not ready

Construction of Spring Boot Project:

image

image

Simulated business scenario Code:

@RestController
public class IndexController {
/***
 * 存big对象
 * @return
 */
@GetMapping("/put")
public String process() {
   ArrayList<User> users = queryUsers();
   for (User user:users){
      //TODO 业务操作
   }
   return "ok";
}
private ArrayList<User> queryUsers() {
   ArrayList<User> users = new ArrayList<>();
   for (int i = 0; i < 50000; i++) {
      users.add(new User(i, "java2b"));
   }
   return users;
}
}
复制代码
public class User {

   private int id;
   private String name;
   private byte[] data;

   public User(int id, String name) {
      this.id = id;
      this.name = name;
      data=new byte[1 * 128 * 1024];
   }
}
复制代码

Output collector information:

/***
 * 打印jvm信息
 * @return
 */
@GetMapping("/info")
public String info() {
   List<GarbageCollectorMXBean> garbages = ManagementFactory.getGarbageCollectorMXBeans();
   StringBuilder stringBuilder = new StringBuilder();
   for (GarbageCollectorMXBean garbage : garbages) {
      stringBuilder.append("垃圾收集器:名称=" + garbage.getName() + ",收集=" + garbage.getCollectionCount() + ",总花费时间="
              + garbage.getCollectionTime());
      // + ",内存区名称=" + Arrays.deepToString(garbage.getMemoryPoolNames()));
      stringBuilder.append("\r\n");
   }
   MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
   MemoryUsage headMemory = memory.getHeapMemoryUsage();
   long MB = 1024 * 1024;
   stringBuilder.append("head堆:");
   stringBuilder.append("\t初始(M):" + headMemory.getInit() / MB);
   stringBuilder.append("\t最大(上限)(M):" + headMemory.getMax() / MB);
   stringBuilder.append("\t当前(已使用)(M):" + headMemory.getUsed() / MB);
   stringBuilder.append("\t提交的内存(已申请)(M):" + headMemory.getCommitted() / MB);
   stringBuilder.append("\t使用率:" + headMemory.getUsed() * 100 / headMemory.getCommitted() + "%");
   return stringBuilder.toString();
}
复制代码

Generating jar package deployed to the server

image

Startup parameters:

java -Xms256m -Xmx256m -verbose:gc -Xloggc:/root/jvm/gc-cms.log -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintHeapAtGC -XX:HeapDumpPath=/root/jvm/dump.hprof -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCTimeStamps -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:+PrintGCDetails -XX:+UseCMSCompactAtFullCollection -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=6666 -Djava.rmi.server.hostname=192.168.0.31 -jar /root/jvm/jvm-web-0.0.1-SNAPSHOT.jar > catalina.out &
复制代码

JVM parameters of significance here for the next spots.

JVM arguments detailed:

JVM arguments meaning
-XX:-CMSPrecleaningEnabled No pre-cleaning, spent the previous article we all know, CMS during this time and concurrent mark and re-mark, there will be a pre-cleanup work, and will try this by waiting 5 seconds to once YGC. In order to avoid time-consuming re-marked in the back of the stage to mark the new generation of the object.
-XX:+UseConcMarkSweepGC This parameter will start the CMS collector. The default is the new generation ParNew, Serial can also be set to the new generation of collectors. This parameter is equivalent to -Xconcgc.
-XX:ParallelGCThreads Because it is a parallel processor, of course, also possible to specify the number of threads. The default number of concurrent threads are: (ParallelGCThreads + 3) / 4).
-XX:ConcGCThreads Or -XX: ParallelCMSThreads; in addition to the above set of threads of the way, you can manually set any of a number of concurrent threads CMS through this two parameters
-XX:CMSInitiatingOccupancyFraction Since the CMS collector is not exclusive, the application is still working at the time of garbage collection, we need to set aside enough memory to the application, otherwise it will trigger FGC. CMS GC and when to run it? It can be set via the parameter, which represents the percentage of memory to use the old era. When this threshold is reached it will be executed CMS. The default is 68. If old's memory is growing rapidly, it is recommended to reduce the threshold to avoid FGC, if growth is slow, it can increase the threshold to reduce the number of CMS GC. Improve throughput.
-XX:+UseCMSCompactAtFullCollection Since the CMS using labeled cleaning algorithm, memory fragmentation can not be avoided. This parameter specifies once defragmented after CMS.
-XX:CMSFullGCsBeforeCompaction Because after each performance will affect defragment, you can use this parameter to set how many times the CMS to conduct a defragmentation, which is memory compression.
-XX:+CMSClassUnloadingEnabled It allows recovery of the class metadata.
-XX:CMSInitiatingPermOccupancyFraction When the permanent zone occupancy rate of this percentage, CMS started recycling (provided that -XX: + CMSClassUnloadingEnabled activated).
-XX:UseCMSInitiatingOccupancyOnly Is performed only represent CMS recovered in time to reach the threshold.
XX:CMSWaitDuration=2000 Because CMS GC conditions are relatively simple, the JVM thread has a regular Old scan region, can specify the time interval (in milliseconds) by this parameter, the default is 2s.

JVM tool parameters:

JVM arguments meaning
-XX:+PrintGCDateStamps Print GC logs timestamp
-XX:+PrintGCDetails Print GC details
-XX:+PrintGCTimeStamps The Indian jvm garbage collection starts running from the time-consuming
-Xloggc: The output of garbage collection information to the specified file
-verbose:gc Print GC logs
-XX:+PrintGCApplicationStopedTime View gc pauses caused by the application
XX + PrintTenuringDistribution Objects promotion log
-XX:+HeapDumpOnOutOfMemoryError Export dump file when memory overflow

image

Start effect:

image

access:

We find that the new generation with the older alternative of cms is parNew

image

Request put:

We see the effect through http access method put after:

Results are as follows:

image

image

image

image

During the operation, we found that a large number of objects into the old era, triggering a full gc, cms been collecting.

Utilization rate reached 99%, cms also did not stop the moment:

image

Log analysis:

image

Log Analyzer version 1.0:

We next analyzed to extract a log

[GC (Allocation Failure) 0K->63K(64K), 0.0047147 secs] 10258K->6780K(46144K), [Metaspace: 3434K->3434K(1056768K)], 0.0047613 secs][Times: user=0.02 sys=0.00, real=0.00 secs]

该日志为四个部分:

Full GC:

表明进行了一次垃圾回收,前面没有Full修饰,表明这是一次Minor GC ,注意它不表示只GC新生代,并且现有的不管是新生代还是老年代都会STW。

Allocation Failure:

表明本次引起GC的原因是因为在年轻代中没有足够的空间能够存储新的数据了。

10258K->6780K(46144K),:单位是KB

三个参数分别为:GC前该内存区域(这里是年轻代)使用容量,GC后该内存区域使用容量,该内存区域总容量。

0.0047613 secs:

该内存区域GC耗时,单位是秒

[Times: user=0.04 sys=0.00, real=0.01 secs]:

分别表示用户态耗时,内核态耗时和总耗时

image

日志分析2.0版本:

采用在线gceasy来进行分析,我们打开网址,然后上传我们生产的gc日志,如图所示:

image

优化问题:

列出了可以优化的4个问题新生代和老年代元空间内存占用情况

image

吞吐量统计:97.39%

image

各各分代的内存变化:

image

CMS垃圾收集器不同时期发生的耗时

image

image

GC发生次数的分类和耗时情况

image

定位问题:

我们通过生产的快照文件来定位问题:

image

image

JProfiler:

下载到本地通过JProfiler打开查看

image

查看大对象:

image

我们不难发现是ArrayList集合占用了96%的内存,那我们来看看哪块代码大量用到了我们ArrayList集合了?

image

找到对应代码

image

通过此代码我们就发现put方法大量用到了ArrayList集合造成的内存溢出OOM

总结:

上述实战相信大家都明白了,大致流程就是:

1、够将SpringBoot项目 模拟真实大批量用户场景

2, the configuration parameters are then deployed JVM generate a log file operation monitoring data

3, confirm the problem by analyzing the log files.

Above code and software needs of friends, you can focus on my micro letter: Java2B, you can own practical operation at a deeper impression.

Today wrote this. Like a good feel welcome focus, your attention is my point Like a good text biggest motivation.

This can be seen are the cattle, to help spot trouble at Like a concern, I continue to bring next CMS and G1 combat PK contrast, graphical comparison look more intuitive.

image

          加关注,不迷路。
复制代码

Guess you like

Origin juejin.im/post/5e16c69ff265da1fea188c10