JVM_05 垃圾回收制(GC调优)

网友投稿 588 2022-05-30

GC 调优

预备知识:

GC相关的VM参数:官方文档

查看虚拟机参数命令:

"C:\Program Files\Java\jdk1.8.0_201\bin\java" -XX:+PrintFlagsFinal -version | findstr "GC"

1

D:\Note\笔记\JDK源码学习\IDEA-workspace\jdk8>"C:\Program Files\Java\jdk1.8.0_201\bin\java" -XX:+PrintFlagsFinal -version | findstr "GC" uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product} uintx AutoGCSelectPauseMillis = 5000 {product} bool BindGCTaskThreadsToCPUs = false {product} uintx CMSFullGCsBeforeCompaction = 0 {product} uintx ConcGCThreads = 0 {product} bool DisableExplicitGC = false {product} bool ExplicitGCInvokesConcurrent = false {product} bool ExplicitGCInvokesConcurrentAndUnloadsClasses = false {product} uintx G1MixedGCCountTarget = 8 {product} uintx GCDrainStackTargetSize = 64 {product} uintx GCHeapFreeLimit = 2 {product} uintx GCLockerEdenExpansionPercent = 5 {product} bool GCLockerInvokesConcurrent = false {product} uintx GCLogFileSize = 8192 {product} uintx GCPauseIntervalMillis = 0 {product} uintx GCTaskTimeStampEntries = 200 {product} uintx GCTimeLimit = 98 {product} uintx GCTimeRatio = 99 {product} bool HeapDumpAfterFullGC = false {manageable} bool HeapDumpBeforeFullGC = false {manageable} uintx HeapSizePerGCThread = 87241520 {product} uintx MaxGCMinorPauseMillis = 4294967295 {product} uintx MaxGCPauseMillis = 4294967295 {product} uintx NumberOfGCLogFiles = 0 {product} intx ParGCArrayScanChunk = 50 {product} uintx ParGCDesiredObjsFromOverflowList = 20 {product} bool ParGCTrimOverflow = true {product} bool ParGCUseLocalOverflow = false {product} uintx ParallelGCBufferWastePct = 10 {product} uintx ParallelGCThreads = 8 {product} bool ParallelGCVerbose = false {product} bool PrintClassHistogramAfterFullGC = false {manageable} bool PrintClassHistogramBeforeFullGC = false {manageable} bool PrintGC = false {manageable} bool PrintGCApplicationConcurrentTime = false {product} bool PrintGCApplicationStoppedTime = false {product} bool PrintGCCause = true {product} bool PrintGCDateStamps = false {manageable} bool PrintGCDetails = false {manageable} bool PrintGCID = false {manageable} bool PrintGCTaskTimeStamps = false {product} bool PrintGCTimeStamps = false {manageable} bool PrintHeapAtGC = false {product rw} bool PrintHeapAtGCExtended = false {product rw} bool PrintJNIGCStalls = false {product} bool PrintParallelOldGCPhaseTimes = false {product} bool PrintReferenceGC = false {product} bool ScavengeBeforeFullGC = true {product} bool TraceDynamicGCThreads = false {product} bool TraceParallelOldGCTasks = false {product} bool UseAdaptiveGCBoundary = false {product} bool UseAdaptiveSizeDecayMajorGCCost = true {product} bool UseAdaptiveSizePolicyWithSystemGC = false {product} bool UseAutoGCSelectPolicy = false {product} bool UseConcMarkSweepGC = false {product} bool UseDynamicNumberOfGCThreads = false {product} bool UseG1GC = false {product} bool UseGCLogFileRotation = false {product} bool UseGCOverheadLimit = true {product} bool UseGCTaskAffinity = false {product} bool UseMaximumCompactionOnSystemGC = true {product} bool UseParNewGC = false {product} bool UseParallelGC := true {product} bool UseParallelOldGC = true {product} java version "1.8.0_201" Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode) bool UseSerialGC = false {product}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

JVM_05 垃圾回收制(GC调优)

68

69

可以根据参数去查询具体的信息:

内存

锁竞争

CPU占用

IO

GC

低延迟/高吞吐量? 选择合适的GC

CMS G1 ZGC

ParallelGC

Zing

首先排除减少因为自身编写的代码而引发的内存问题:

查看Full GC前后的内存占用,考虑以下几个问题:

数据是不是太多?

resultSet = statement.executeQuery("select * from 大表");

数据表示是否太臃肿?

对象图

对象大小,Java中new一个Object或者包装类型对象,至少16字节。

是否存在内存泄漏?

static Map map = HashMap(),当我们不断的向静态的map中新增对象且不移除,就可能造成内存吃紧。

可以使用软引用,弱引用来解决上面的问题,因为它们可以在内存吃紧时,被定期回收。也可以使用第三方的缓存中间件来存储上面的map中的数据。

新生代的特点:

当我们new一个对象时,会先在伊甸园中进行分配,所有的new操作分配内存都是非常廉价且速度极快的

TLAB(Thread-Location Allocation Buffer):当我们new一个对象时,会先检查TLAB缓冲区中是否有可用内存,如果有则优先在TLAB中进行对象分配。

死亡对象回收的代价为零

大部分对象用过即死(朝生夕死)

MInor GC 所用时间远小于Full GC

新生代内存越大越好么?

不是:

新生代内存太小:频繁触发Minor GC,会 STW,会使得吞吐量下降。

新生代内存太大:老年代内存占比有所降低,会更频繁地触发Full GC。而且触发Minor GC时,清理新生代所花费的时间会更长。

新生代内存设置为能容纳 并发量*(请求-响应) 的数据为宜。

幸存区最大能够保存 当前活跃对象+需要晋升的对象。

晋升阈值配置得当,让长时间存活的对象尽快晋升。

以CMS为例:

CMS的老年代内存越大越好。

先尝试不做调优,如果没有 Full GC 那么说明当前系统暂时不需要优化,否则,就先尝试调优新生代。

观察发生Full GC 时老年代的内存占用,将老年代内存预设调大 1/4 ~ 1/3。

-XX:CMSInitiatingOccupancyFraction=percent

当Full GC 和 Minor GC 调用频繁。

当请求高峰期发生Full GC,单次暂停时间特别长(CMS)

在老年代充裕的情况下,发生Full GC (1.7)

上面集中情况都是需要调优的!

JVM

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:ApiPost-预(后)执行脚本常用方法集合
下一篇:API及SDK介绍
相关文章