52.【面试宝典】面试宝典-JVM参数配置实战

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【面试宝典】面试宝典-JVM参数配置实战

前文如下:

51.【面试宝典】面试宝典-JVM参数概述


1.jvm参数配置

1.1 查看测试环境

### jdk版本 openjdk11
java -version
openjdk version "11.0.12" 2021-07-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.12+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.12+7-LTS, mixed mode, sharing)
###cpu 信息
#查看cpu信息,内容较多不展示
cat /proc/cpuinfo |grep name|cut -f2 -d: |uniq -c
cat /proc/cpuinfo
#查看物理cpu个数  --1个
cat /proc/cpuinfo |grep "physical id" |sort |uniq|wc -l
1
cat /proc/cpuinfo |grep "physical id" |sort |uniq
physical id : 0
cat /proc/cpuinfo |grep "physical id" |wc -l
8
cat /proc/cpuinfo |grep "physical id"
physical id : 0
physical id : 0
physical id : 0
physical id : 0
physical id : 0
physical id : 0
physical id : 0
physical id : 0
#查看每个物理cpu core核心数  --每个都是4个
 cat /proc/cpuinfo |grep "cpu cores" |uniq
cpu cores : 4
cat /proc/cpuinfo |grep "cpu cores" |wc -l
cpu cores : 4
cpu cores : 4
cpu cores : 4
cpu cores : 4
cpu cores : 4
cpu cores : 4
cpu cores : 4
cpu cores : 4
#查看逻辑cpu 个数
cat /proc/cpuinfo |grep "processor" |wc -l
8
## 1个物理cpu;4核;支持超线程; 8个逻辑cpu
## cpu总核数=物理cpu个数*每颗cpu核数;
## 逻辑cpu个数=物理cpu个数*每颗cpu核数*超线程数
###内存大小  14(预估16左右)
free -h
              total        used        free      shared  buff/cache   available
Mem:           14Gi       9.3Gi       4.9Gi       2.0Mi       730Mi       5.4Gi
Swap:            0B          0B          0B
### 操作系统信息  linux
uname -a
Linux 127.0.0.1 4.18.0-305.3.1.el8.x86_64 #1 SMP Tue Jun 1 16:14:33 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
cat /proc/version 
Linux version 4.18.0-305.3.1.el8.x86_64 (mockbuild@kbuilder.bsys.centos.org) 
(gcc version 8.4.1 20200928 (Red Hat 8.4.1-1) (GCC)) #1 SMP Tue Jun 1 16:14:33 UTC 2021
复制代码

1.2 查看启动参数

#设置启动参数
 ## 测试工程
 export PRO_NAME=test-project
 ## 工程目录
 export DEPLOY_PATH=/home/admin/java/test-project
 ## 启动参数
 export JAVA_OPTS="-server -Xms3072M -Xmx3072M  -XX:PretenureSizeThreshold=64m -XX:
 -OmitStackTraceInFastThrow -XX:+PrintCommandLineFlags -XX:MetaspaceSize=600m 
 -XX:MaxMetaspaceSize=600m -XX:+HeapDumpOnOutOfMemoryError 
 -XX:HeapDumpPath=/home/admin/java/test-project/logs/ 
 -Xlog:gc*,gc+ref=debug,gc+heap=debug,gc+age=trace:file=logs/gc.log:tags,uptime,time
 ,level:filecount=10,filesize=200m"
#设置启动脚本 
 exec nohup java -Dproject.home=$DEPLOY_PATH $JAVA_OPTS -jar $PRO_NAME >> /dev/null 2>&1 &
#查看启动进程
[admin@ 127.0.0.1]$ ps -ef|grep java
admin    1345636       1  2 Aug27 ?        
04:55:38 java -Dproject.home=/home/admin/java/test-project -server -Xms3072M -Xmx3072M -XX:PretenureSizeThreshold=64m -XX:-OmitStackTraceInFastThrow -XX:+PrintCommandLineFlags -XX:MetaspaceSize=600m 
-XX:MaxMetaspaceSize=600m -XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/home/admin/java/test-project/logs/ 
-Xlog:gc*,gc+ref=debug,gc+heap=debug,gc+age=trace:file=logs/gc.log:tags,uptime,time,
level:filecount=10,filesize=200m 
-jar test-project.jar
[admin@ 127.0.0.1]$ jps
1345636 test-project.jar
2245365 Jps
复制代码

2 解析参数

JAVA_OPTS="
-server     #server模式
-Xms3072M   #初始堆大小
-Xmx3072M  #最大堆大小
-XX:PretenureSizeThreshold=64m  #对象超过多大是直接在老年代分配
-XX:-OmitStackTraceInFastThrow  #关闭 Fast Throw优化,注意是-号,不是+号
-XX:+PrintCommandLineFlags  ## PrintCommandLineFlags
-XX:MetaspaceSize=600m   ## 元空间大小 影响Full GC
-XX:MaxMetaspaceSize=600m  ## 最大元空间大小 影响Full GC
-XX:+HeapDumpOnOutOfMemoryError ##当JVM发生OOM时,自动生成DUMP文件
-XX:HeapDumpPath=/home/admin/java/test-project/logs/  ##dump日志地址
-Xlog:gc*,gc+ref=debug,gc+heap=debug,gc+age=trace:file=logs/gc.log:tags,uptime,time
 ,level:filecount=10,filesize=200m"  
 ## jvm1.9新特性 有点类似于将jvm不同事件不同日志级别想看的日志内容做了内容,日志级别和目录细分,可以通过相关参数去配置
复制代码

3.知识扩展:

  1. PretenureSizeThreshold\
    -XX:PretenureSizeThreshold的默认值和作用浅析
    讲到大对象主要指字符串和数组,虚拟机提供了一个-XX:PretenureSizeThreshold参数,大于这个值的参数直接在老年代分配。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存复制(新生代采用复制算法)。 说白了就是设置多大的大对象,直接进入老年代,避免年轻代过多的minor gc(来回复制)
    找到了一篇相关问题的文章《Frequently Asked Questions about Garbage Collection in the HotspotTM JavaTM Virtual Machine》

第29条:Do objects ever get allocated directly into the old generation? In 1.4.1 there two situations where allocation may occur directly into the old generation. 有两种情况,对象会直接分配到老年代。 If an allocation fails in the young generation and the object is a large array that does not contain any references to objects, it can be allocated directly into the old generation. In some select instances, this strategy was intended to avoid a collection of the young generation by allocating from the old generation. 如果在新生代分配失败且对象是一个不含任何对象引用的大数组,可被直接分配到老年代。 通过在老年代的分配避免新生代的一次垃圾回收。 There is a flag (available in 1.4.2 and later) l-XX:PretenureSizeThreshold= that can be set to limit the size of allocations in the young generation. Any allocation larger than this will not be attempted in the young generation and so will be allocated out of the old generation. XX:PretenureSizeThreshold=<字节大小>可以设分配到新生代对象的大小限制。 任何比这个大的对象都不会尝试在新生代分配,将在老年代分配内存。 The threshold size for 1) is 64k words. The default size for PretenureSizeThreshold is 0 which says that any size can be allocated in the young generation. PretenureSizeThreshold 默认值是0,意味着任何对象都会现在新生代分配内存。

  1. OmitStackTraceInFastThrow异常栈信息不见了之JVM参数
    jdk 1.6开始,默认server模式下开启了这个参数,意为当jvm检测到程序在重复抛一个异常,在执行若干次后会将异常吞掉堆栈打印信息,即 Fast Throw

JVM只对几个特定类型异常开启了Fast Throw优化,这些异常包括:

  • NullPointerException
  • ArithmeticException
  • ArrayIndexOutOfBoundsException
  • ArrayStoreException
  • ClassCastException

相关解决问题:项目日志只打印 java.lang.NullPointerException信息,没有打印相关堆栈信息

经过一番代码调试,确定并非程序代码问题。没有线索之后,从Google找到了答案:是因为在server模式下运行的时候,有一个默认选项是-XX:+OmitStackTraceInFastThrow,这个玩意的意思就是当大量抛出同样的异常的后,后面的异常输出将不打印堆栈,打印堆栈的时候底层会调用到Throwable.getOurStackTrace()方法,而这个方法是synchronized的,对性能有比较明显对影响。所以这个参数是合理的。正常情况下,如果打印了几万条异常堆栈是很容易发现问题的。但是我们的系统正好赶上访问量高峰,一不留神就错过打印详细堆栈的阶段了。 说明:JVM默认开启了Fast Throw优化。如果想关闭这个优化,很简单,配置-XX:-OmitStackTraceInFastThrow, 恢复开启Fast Throw设置 -XX:+OmitStackTraceInFastThrow`即可。

  1. PrintCommandLineFlags  :JVM调优:-XX:+PrintCommandLineFlags 查看程序使用的默认JVM参数.
  2. MetaspaceSize和MaxMetaspaceSize :元空间大小,基于本地内存大小,jdk1.8引入. MetaspaceSize容量触发FGC的阈值。比如-XX:MetaspaceSize=256m,当MetaspaceSize容量超过256M时触发FGC,超过设定阈值后MetaspaceSize每扩容一次触发一次FGC。需要和永久代区分.
    建议
    MetaspaceSizeMaxMetaspaceSize设置一样大; 具体设置多大,建议稳定运行一段时间后通过jstat -gc pid确认且这个值大一些,对于大部分项目256m即可.
    JDK7的PermSize(永久代)
    JDK8+移除了Perm,引入了Metapsace,它们两者的区别是什么呢?Metaspace上面已经总结了,无论-XX:MetaspaceSize-XX:MaxMetaspaceSize两个参数如何设置,随着类加载越来越多不断扩容调整,直到MetaspaceSize(如果没有配置就是默认20.8m)触发FGC,上限是-XX:MaxMetaspaceSize默认是几乎无穷大(基于本地内存大小)。而Perm的话,我们通过配置-XX:PermSize以及-XX:MaxPermSize来控制这块内存的大小,jvm在启动的时候会根据-XX:PermSize初始化分配一块连续的内存块,这样的话,如果-XX:PermSize设置过大,就是一种浪费。很明显,Metapspace比Perm可控;后续可以细讲 ,待定.....
  3. HeapDumpOnOutOfMemoryError和HeapDumpPath :-XX:+HeapDumpOnOutOfMemoryError参数表示当JVM发生OOM时,自动生成DUMP文件,后续可以细讲如何查看dump日志 ,待定.....
    JVM参数-XX:+HeapDumpOnOutOfMemoryError使用方法
    -XX:HeapDumpPath=${目录}参数表示生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java_<pid>_<date>_<time>_heapDump.hprof。
  4. xlog :    
    JDK9的新特性:JVM的xlog
    JDK9的新特性:JVM的xlog-阿里云开发者社区 (aliyun.com)
    在java程序中,我们通过日志来定位和发现项目中可能出现的问题。在现代java项目中,我们使用log4j或者slf4j,Logback等日志记录框架来处理日志问题。JVM是java程序运行的基础,JVM中各种事件比如:GC,class loading,JPMS,heap,thread等等其实都可以有日志来记录。通过这些日志,我们可以监控JVM中的事件,并可以依次来对java应用程序进行调优。 在JDK9中引入的Xlog日志服务就是为这个目的而创建的。通过xlog,JDK将JVM中的各种事件统一起来,以统一的形式对外输出。通过tag参数来区分子系统,通过log level来区分事件的紧急性,通过logging output来配置输出的地址。使用java -Xlog:help命令我们看一下xlog的基本格式:
-Xlog Usage: -Xlog[:[selections][:[output][:[decorators][:output-options]]]]
     where 'selections' are combinations of tags and levels of the form tag1[+tag2...][*][=level][,...]
     NOTE: Unless wildcard (*) is specified, only log messages tagged with exactly the tags specified will be matched.
# 1.selections
## selections表示的是到底需要输出哪些信息。是以tag=level来表示的。
## 1.1 tag表示的是JVM中的事件或者子系统 
> 相关参数 Available log tags:
>  add, age, alloc, annotation, aot, arguments, attach, barrier, biasedlocking, blocks, bot, breakpoint, bytecode, cds, census, class, classhisto, cleanup, codecache, compaction, compilation, constantpool, constraints, container, coops, cpu, cset, data, datacreation, dcmd, decoder, defaultmethods, director, dump, dynamic, ergo, event, exceptions, exit, fingerprint, free, freelist, gc, handshake, hashtables, heap, humongous, ihop, iklass, init, inlining, install, interpreter, itables, jfr, jit, jni, jvmti, liveness, load, loader, logging, malloc, mark, marking, membername, memops, metadata, metaspace, methodcomparator, mirror, mmu, module, monitorinflation, monitormismatch, nestmates, nmethod, normalize, numa, objecttagging, obsolete, oldobject, oom, oopmap, oops, oopstorage, os, pagesize, parser, patch, path, perf, periodic, phases, plab, preorder, preview, promotion, protectiondomain, ptrqueue, purge, record, redefine, ref, refine, region, reloc, remset, resolve, safepoint, sampling, scavenge, setting, smr, stackmap, stacktrace, stackwalk, start, startuptime, state, stats, streaming, stringdedup, stringtable, subclass, survivor, sweep, symboltable, system, table, task, thread, time, timer, tlab, tracking, unload, unshareable, update, verification, verify, vmmutex, vmoperation, vmthread, vtables, vtablestubs, workgang
>  Specifying 'all' instead of a tag combination matches all tag combinations
## 1.2 levels表示的是日志的级别  
> 相关参数 Available log levels:
> off, trace, debug, info, warning, error
## 1.3 例如
java -Xlog:os,class=info -version   
[admin@127.0.0.1]$ java -Xlog:os,class=info -version   
[0.001s][info][os] Use of CLOCK_MONOTONIC is supported
[0.001s][info][os] Use of pthread_condattr_setclock is supported
[0.001s][info][os] Relative timed-wait using pthread_cond_timedwait is associated with CLOCK_MONOTONIC
[0.001s][info][os] HotSpot is running with glibc 2.28, NPTL 2.28
[0.001s][info][os] SafePoint Polling address, bad (protected) page:0x00007f0a8558e000, good (unprotected) page:0x00007f0a8558f000
[0.001s][info][os] attempting shared library load of /usr/lib/jvm/java-11-openjdk-11.0.12.0.7-0.el8_4.x86_64/lib/libzip.so
[0.002s][info][os] shared library load of /usr/lib/jvm/java-11-openjdk-11.0.12.0.7-0.el8_4.x86_64/lib/libzip.so was successful
openjdk version "11.0.12" 2021-07-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.12+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.12+7-LTS, mixed mode, sharing)
# 2. output    
## 2.1 output表示将日志输出到什么地方。    
## 2.2 output的可选项:
  stdout/stderr
  file=<filename>
## stdout表示标准输出,stderr表示标准错误。file表示输出到文件里面。
## 2.3 例如
java -Xlog:all=debug:file=test-protect-ttt.log -version    
[admin@127.0.0.1]$ java -Xlog:all=debug:file=test-protect-ttt.log -version
openjdk version "11.0.12" 2021-07-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.12+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.12+7-LTS, mixed mode, sharing) 
[admin@127.0.0.1]$ ll -h test-protect-ttt.log 
-rw-rw-r-- 1 admin admin 602K Aug 27 22:44 test-protect-ttt.log
[admin@127.0.0.1]$ more test-protect-ttt.log     
more test-protect-ttt.log 
[0.001s][debug][os] Initial active processor count set to 8
[0.001s][debug][os,container] container memory limit unlimited: -1, using host value
[0.001s][debug][os,container] container memory limit unlimited: -1, using host value
[0.001s][debug][ergo        ] ThreadLocalHandshakes enabled.
[0.001s][info ][os          ] Use of CLOCK_MONOTONIC is supported
[0.001s][info ][os          ] Use of pthread_condattr_setclock is supported
[0.001s][info ][os          ] Relative timed-wait using pthread_cond_timedwait is associated with CLOCK_MONOTONIC
[0.001s][info ][os          ] HotSpot is running with glibc 2.28, NPTL 2.28
[0.001s][info ][os          ] SafePoint Polling address, bad (protected) page:0x00007fbd7c527000, good (unprotected) page:0x00007fbd7c528000
[0.001s][debug][perf,memops ] PerfDataMemorySize = 32768, os::vm_allocation_granularity = 4096, adjusted size = 32768
[0.001s][debug][perf,memops ] PerfMemory created: address = 0x00007fbd7c418000, size = 32768
[0.001s][info ][biasedlocking] Aligned thread 0x00007fbd740186a0 to 0x00007fbd74018800
[0.001s][info ][os,thread    ] Thread attached (tid: 2284746, pthread id: 140451811297024).  ### 内容较多忽略.....................
# 3. decorators   
## 3.1 decorators表示输出哪些内容到日志中。    
> 相关参数:time (t), utctime (utc), uptime (u), timemillis (tm), uptimemillis (um), timenanos (tn), uptimenanos (un), hostname (hn), pid (p), tid (ti), level (l), tags (tg)
>  Decorators can also be specified as 'none' for no decoration
## 3.2 例如
java -Xlog:gc*=debug:stdout:time,uptimemillis,tid -version
[admin@127.0.0.1]$ java -Xlog:gc*=debug:stdout:time,uptimemillis,tid -version
[2022-08-27T22:47:37.731+0800][2ms][2285793] Heap region size: 1M
[2022-08-27T22:47:37.731+0800][2ms][2285793] Minimum heap 8388608  Initial heap 251658240  Maximum heap 4013948928
[2022-08-27T22:47:37.732+0800][3ms][2285793] ConcGCThreads: 2 offset 16
[2022-08-27T22:47:37.732+0800][3ms][2285793] ParallelGCThreads: 8
[2022-08-27T22:47:37.732+0800][3ms][2285793] Initialize mark stack with 4096 chunks, maximum 16384
[2022-08-27T22:47:37.732+0800][3ms][2285793] Expand the heap. requested expansion amount: 251658240B expansion amount: 251658240B
[2022-08-27T22:47:37.735+0800][6ms][2285793] Target occupancy update: old: 0B, new: 251658240B
[2022-08-27T22:47:37.735+0800][6ms][2285793] Initial Refinement Zones: green: 8, yellow: 24, red: 40, min yellow size: 16
[2022-08-27T22:47:37.735+0800][6ms][2285793] Using G1
[2022-08-27T22:47:37.735+0800][6ms][2285793] Heap address: 0x0000000710c00000, size: 3828 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
[2022-08-27T22:47:37.735+0800][6ms][2285793] Attempt heap expansion (allocate archive regions). Total size: 1048576B
[2022-08-27T22:47:37.735+0800][6ms][2285793] Mark closed archive regions in map: [0x00000007bff00000, 0x00000007bff6aff8]
[2022-08-27T22:47:37.735+0800][6ms][2285793] Attempt heap expansion (allocate archive regions). Total size: 1048576B
[2022-08-27T22:47:37.735+0800][6ms][2285793] Mark open archive regions in map: [0x00000007bfe00000, 0x00000007bfe47ff8]
openjdk version "11.0.12" 2021-07-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.12+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.12+7-LTS, mixed mode, sharing)
[2022-08-27T22:47:37.758+0800][29ms][2285797] Stopping 0
[2022-08-27T22:47:37.758+0800][29ms][2285793] Heap
[2022-08-27T22:47:37.758+0800][29ms][2285793]  garbage-first heap   total 247808K, used 1740K [0x0000000710c00000, 0x0000000800000000)
[2022-08-27T22:47:37.758+0800][29ms][2285793]   region size 1024K, 2 young (2048K), 0 survivors (0K)
[2022-08-27T22:47:37.758+0800][29ms][2285793]  Metaspace       used 120K, capacity 4480K, committed 4480K, reserved 1056768K
[2022-08-27T22:47:37.759+0800][30ms][2285793]   class space    used 2K, capacity 384K, committed 384K, reserved 1048576K
复制代码

今天先实战配置一下jvm参数,明天看看具体日志输出怎么解析(后续还有待定的两个任务:一个是分析一下永久代和元空间,还有一个是如何查看dump日志)


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6天前
|
存储 监控 Java
JVM实战—8.如何分析jstat统计来定位GC
本文详细介绍了使用jstat、jmap和jhat等工具分析JVM运行状况的方法,以及如何合理优化JVM性能。内容涵盖新生代与老年代对象增长速率、Young GC和Full GC的触发频率及耗时等关键指标的分析。通过模拟BI系统和计算系统的案例,展示了如何根据实际场景调整JVM参数以减少FGC频率,提升系统性能。最后汇总了常见问题及其解决方案,帮助开发者更好地理解和优化JVM运行状态。
JVM实战—8.如何分析jstat统计来定位GC
|
5天前
|
缓存 监控 算法
JVM实战—10.MAT的使用和JVM优化总结
本文详细探讨了JVM内存管理与性能优化的关键问题。首先分析了线上大促活动引发的老年代内存泄漏及频繁FGC问题,通过MAT工具定位到本地缓存未正确处理的原因,并提出使用Ehcache等框架解决。接着讨论了百万级数据误处理导致的频繁FGC案例,深入剖析String.split()方法在特定JDK版本下的内存消耗问题,并给出多线程并发处理大数据量的优化建议。文章还总结了JVM运行原理、GC机制以及YGC和FGC的触发条件,明确了正常系统GC频率指标。最后提供了JVM性能优化的整体思路,包括新系统开发时的参数预估、压测后的调整策略以及线上系统的监控方法,同时列举了常见的FGC原因及对应解决方案。
119 79
JVM实战—10.MAT的使用和JVM优化总结
|
4天前
|
消息中间件 缓存 Java
JVM实战—11.OOM的原因和模拟以及案例
本文详细探讨了Java系统中内存溢出(OutOfMemory,简称OOM)问题的成因与解决方法。首先分析了线上系统因OOM挂掉的常见场景及处理思路,接着深入讲解了JVM中可能发生OOM的三大区域:Metaspace(类信息存储区)、栈内存(线程执行方法时使用)和堆内存(对象存储区)。针对每个区域,文章通过具体代码示例模拟了内存溢出的情况,如动态生成过多类导致Metaspace溢出、无限递归调用引发栈内存溢出以及高负载下堆内存不足等问题。最后结合实际案例,如大数据处理系统因Kafka故障未正确处理数据缓存而导致OOM,以及无限循环调用或未缓存动态代理类引发的问题,给出了预防和改进措施。
100 64
JVM实战—11.OOM的原因和模拟以及案例
|
7天前
|
存储 监控 Java
JVM实战—7.如何模拟GC场景并阅读GC日志
本文主要介绍了:如何动手模拟出频繁Young GC的场景、JVM的Young GC日志应该怎么看、编写代码模拟动态年龄判定规则进入老年代、编写代码模拟S区放不下部分进入老年代、JVM的Full GC日志应该怎么看。
JVM实战—7.如何模拟GC场景并阅读GC日志
|
7天前
|
消息中间件 存储 算法
JVM实战—6.频繁YGC和频繁FGC的后果
本文详细探讨了JVM中的GC机制及其优化策略,涵盖Young GC、Old GC和Full GC的触发条件与影响。首先分析了JVM GC可能导致系统卡顿的问题,特别是大内存机器上的YGC性能瓶颈,并通过G1垃圾回收器解决。接着通过实际案例展示了频繁FGC的成因及优化方法,如调整新生代与老年代内存比例或使用大内存机器。最后总结了不同GC算法的适用场景及对象生命周期特点,为JVM性能调优提供了实用指导。
JVM实战—6.频繁YGC和频繁FGC的后果
|
6天前
|
SQL 缓存 监控
JVM实战—9.线上FGC的几种案例
本文详细探讨了JVM性能优化中的几个关键案例与问题。首先分析了如何优化每秒十万QPS的社交APP,通过增加Survivor区大小和优化内存碎片解决频繁Full GC的问题。接着讨论了垂直电商后台系统FGC的深度优化,定制JVM参数模板以降低GC频率。还探讨了不合理设置JVM参数导致频繁FGC的情况,并提出了解决方案。此外,针对线上系统每天数十次FGC的问题,定位到大对象是主要原因,并通过调整新生代大小等参数优化。同时,分析了电商大促活动中因System.gc()调用导致系统卡死的现象,建议禁用显式GC。
JVM实战—9.线上FGC的几种案例
|
10天前
|
缓存 算法 Java
JVM实战—4.JVM垃圾回收器的原理和调优
本文详细探讨了JVM垃圾回收机制,包括新生代ParNew和老年代CMS垃圾回收器的工作原理与优化方法。内容涵盖ParNew的多线程特性、默认线程数设置及适用场景,CMS的四个阶段(初始标记、并发标记、重新标记、并发清理)及其性能分析,以及如何通过合理分配内存区域、调整参数(如-XX:SurvivorRatio、-XX:MaxTenuringThreshold等)来优化垃圾回收。此外,还结合电商大促案例,分析了系统高峰期的内存使用模型,并总结了YGC和FGC的触发条件与优化策略。最后,针对常见问题进行了汇总解答,强调了基于系统运行模型进行JVM参数调优的重要性。
JVM实战—4.JVM垃圾回收器的原理和调优
|
3天前
|
缓存 监控 Java
JVM实战—12.OOM的定位和解决
本文详细探讨了JVM内存管理中的常见问题及其解决方案,包括如何监控和报警系统的OOM异常、在内存溢出时自动Dump内存快照、解决Metaspace区域内存溢出、栈内存溢出(StackOverflowError)以及堆内存溢出(OutOfMemoryError: Java heap space)。针对每种情况,文章提供了具体的解决思路、示例代码、GC日志分析及内存快照分析方法。通过搭建系统监控体系、调整JVM参数和使用工具如MAT,可以有效定位和解决各类内存问题,优化系统性能并避免崩溃风险。
JVM实战—12.OOM的定位和解决
|
12天前
|
消息中间件 Java 应用服务中间件
JVM实战—2.JVM内存设置与对象分配流转
本文详细介绍了JVM内存管理的相关知识,包括:JVM内存划分原理、对象分配与流转、线上系统JVM内存设置、JVM参数优化、问题汇总。
JVM实战—2.JVM内存设置与对象分配流转
|
11天前
|
消息中间件 存储 算法
JVM实战—3.JVM垃圾回收的算法和全流程
本文详细介绍了JVM内存管理与垃圾回收机制,涵盖以下内容:对象何时被垃圾回收、垃圾回收算法及其优劣、新生代和老年代的垃圾回收算法、Stop the World问题分析、核心流程梳理。
JVM实战—3.JVM垃圾回收的算法和全流程

相关实验场景

更多