JVM learning - garbage collection GC (the learning process)

JVM learning - garbage collection (GC)

2020 February 19 06:03:56 start learning garbage collection, learning sources (JVM teacher Zhang Long Course)

JVM memory data area Knowledge Review

Before learning garbage collection, to have a detailed understanding of the internal JVM memory area. Prior knowledge of the contents of the relevant memory region were reviewed and summarized, lay the foundation for learning garbage collection.

image-20200219060429726

The gray area is the thread shared

The white area is isolated thread

image-20200219064036596

image-20200219064120088

image-20200219064229291

Reference 4 bytes, 8 bytes of null objects.

After performing the method, the corresponding stack Stack variables immediately recovered, but the Heap object until GC recovered.

JVM garbage collection (Garbage Collection)

Theoretical knowledge

JVM garbage collection (GC) model

  1. Garbage judgment algorithm
  2. GC algorithm
  3. Implementation and selection of the garbage collector

Garbage judgment algorithm

  1. Reference counting algorithm (Reference Counting)
  2. Root search algorithm (GC Roots Tracing)

Reference counting algorithm

image-20200219064625169

The problem object referenced by the end of the cycle: A reference to B, B and references A. Even without external references. But it has been a state, so it can not be recovered.

image-20200219064807017

Of course, he still can circumvent this shortcoming by other means.

Root search algorithm

image-20200219070328494

image-20200219070437201

Methods district

image-20200219070745942

Garbage collection (GC) algorithm

  1. Mark - sweep algorithm (Mark-Sweep)
  2. Mark - Collation Algorithm (Mark-compact)
  3. Replication algorithm (Copying)
  4. Generational algorithm (Generational): Almost all virtual machines using this algorithm

Why copy algorithm in the new generation of multi-use it? Because most of java java objects are enrollment is extinguished. Not much can be recycled. Old's long life cycle, it is not convenient to use the copy algorithm.

So old's use of clearly marked and labeled Collation Algorithm

Mark - clear algorithm (Mark-Sweep)

image-20200219071343749

Mark - clear Algorithm: Schematic is performed as follows

These objects are subject to the following

image-20200219072023671

Runtime Stack virtual machine stack is the entrance to the root of the search algorithm

image-20200219072122102

First mark

image-20200219072157821

Circular references between J - F. But DG -FJM are to be recovered out. Green is also retained.

After executing the procedure is shown below

Clear again

image-20200219072245947

image-20200219072301392

Copy (Copying) collection algorithm

image-20200219072438309

Simple, efficient operation: however: the need to reduce the memory to the original general costly.

image-20200219072606909

Now mainly used to recover the Cenozoic

image-20200219073336674

在老年代中,一般不能直接选用这种算法。(因为老年代的存活率高 )

复制搜集算法的示意图

  1. 把A- C=复制

image-20200219073521882

把相互引用的都给复制

image-20200219073711606

余下的没有被复制,会被连锅端掉

image-20200219073746128

复制搜集算法优点

image-20200219073803923

标记-整理算法

image-20200219073918760

如下为执行示意图

标记移动。腾出来连续的空间。没有内存碎片。就是有点慢。

image-20200219073959046

image-20200219074030501

分代收集算法(Generational Collecting)

image-20200219074425744

新生代 和 老年代 的定义

新生代:部分刚新生的对象,没有用的

老年代:经历多次垃圾回收,还会保留

image-20200219074816247

JVM6时候的参考(现在已经没有永久代了)

image-20200219074836178

image-20200219075017841

为什么说只会浪费百分之十呢,这里二娃给我讲述的

这次 设置了2个Survivor是非常巧妙的。第一次的时候,8+1 被使用。复制完之后。放入另外一个Survivor。然后下一次的时候。8+另外一个1,把对象复制到1上。所以就完成了,轮流替换。每次被闲置的就会只有一个占用百分之10的Survivor来准备接受要复制的对象。over。

image-20200219075635735

JVM启动的时候可以根据程序的需要,选择一定的需求所对应的垃圾收集器和对应的垃圾收集算法。

image-20200219075742489

内存相关概念

内存结构

image-20200219075826778

内存分配

image-20200219080003520

内存回收

image-20200219080025676

强引用,软引用,弱引用,虚引用

image-20200219080154476

软引用:内存不够的时候,一会被会GC,长期不用也会被收集

垃圾收集算法

image-20200219080244760

黄色区域应用在年轻代

灰色区域应用在老年代

GC触发的时机

image-20200219080326960

尽量避免对Full GC的使用,因为全局GC调用的时候,会停滞所有的义务代码执行。

MinorGC是一定会有的。

垃圾回收器

垃圾回收器理论分析

没有万能的垃圾回收器,交互性和吞吐率是不兼容的,没有银弹

image-20200219080629770

垃圾收集器的“并行”和“并发”

image-20200219081106164

让用户线程处于等待状态是一个很恐怖的事情。

收集器

Serial收集器

STW(Stop The World) 暂停所有的工作线程

虚拟机运行Client模式下的默认收集器

image-20200219081155185

image-20200219081227092

单线程的GC。

ParNew收集器

Serial的多线程版本。其他都一样

image-20200219081416624

image-20200219081532679

Parallel Scavenge收集器

image-20200219081637673

允许较长较长时间的STW。

Serial Old收集器

image-20200219081722260

Parallel Old收集器

image-20200219081731864

image-20200219081742646

CMS收集器:实现非常复杂的收集器

image-20200219094602469

image-20200219094637936

image-20200219094655006

image-20200219094720256

image-20200219094735395

综上,PPT 都需要自己详细读读。

再次回顾一下JVM的内存数据区域的分配情况

image-20200219092857424

  1. Oracle的HotSpot虚拟机,将 java虚拟机方法栈和本地方法栈放在同一个地方
  2. 程序计数器是唯一一个没有要求说必须要使用GC垃圾回收的地方。
  3. 白色的地方是线程独有的

总结

  • 垃圾判断算法
    • 引用计数算法
    • 根搜索算法
  • 垃圾回收GC算法(常见的)
    • 标记-清除算法
    • 标记-整理算法
    • 复制算法(8-1-1)
    • 分代算法(综合前面几种,针对不同的类型,采用不同的算法)
  • 垃圾收集器
    • Serial
    • ParNew
    • Parallel Scavenger (PS (jdk1.8默认的新生代垃圾收集器))
    • Parallel Old(ParOld jdk1.8默认的老年代垃圾收集器)
    • Serial Old
    • CMS

Java内存泄露的经典原因

  1. 对象定义在错误的范围(Wrong Scope)
  2. 异常(Exception)处理不当
  3. 集合数据管理不当

对象定义在错误的范围

image-20200219095147567

从成员变量 移动到 局部变量。 (布局就不一样了。变量会被及时回收)

异常处理不当

image-20200219095332632

异常处理的不到位,关闭流的操作,应该放置在finally里面。

image-20200219095408581

集合数据管理不当

image-20200219095427055

垃圾回收日志(GC Log)

上案例:

image-20200219100059547

这里需要注意点是:数组是原生数据类型。 数组里面的默认值都是0。如果是引用类型的数组,里面的值都为null。

程序初始:

平淡无奇

image-20200219100226243

输出结果:平淡无奇:

image-20200219100816679

接下来添加一定的JVM参数,进行启动,就变得大不一样

JVM参数加 -verbise:gc : 添加垃圾回收GC的详细信息

JVM参数加 Xms20M Xmx20m:分别表示堆容量的初始值和最大值,一般都设置为一样。固定位20M

JVM参数加-XMn10M:表示新生代的容量大小为10M

JVM参数加-XX:+PrintGCDetails:打印GC的详细信息

JVM参数加-XX:SurvivorRatio=8:表示Even空间和Survivor的比例是8:1:1

image-20200219100657109

运行结果:只有GC详情,但是未执行GC

这东西都是:-XX:+PrintGCDetails 打印的,还没有展现GC、

在程序中,再加入一行 代码,再加一个数组(大小就到达GC临界点)

image-20200219101210887

运行结果:GC就出来了

image-20200219101121573

image-20200219101313534

随着程序的变化,内存空间的修改。会导致不同的打印结果出现。

GC:表示 minor GC ,后面数据的含义和格式

​ Allocation Failure:分配失败

​ PSYoungGen:年轻代 PS(Parallel Scavenger 收集器)。

​ 执行前-执行后(总容量):(7694k->624k(9216k))

​ 执行GC之前堆的大小-执行后的存活对象的大小(堆的大小):(5656k->4728k(19456k))

image-20200219102735659

4104k对应的,正好是老年代新增的 大小。(从新生代释放出来,进入老年代)

Full GC 会导致程序暂停 (2,2,2,2 会出现Full GC, 2,2,3,3 反而不会进入Full GC)

没进入Full GC的原因:当新生代已经无法容纳要生成的对象的时候,直接放入老年代

验证的概念如下:GC的触发时机

image-20200219101421689

对于网上的文章或者概念,还有书本等等。里面的内容都是不确定是对的,唯一能验证概念的,就是通过代码,通过数据去看结论。

JVM参数

image-20200219094720256

image-20200219094735395

java -XX:+PrintCommandLineFlags -version :输出启动参数和java版本

image-20200219110007233

-XX:+UseParallelGC : 默认使用的GC是 Parallel

-XX:PretenureSizeThreshold=4194304:大小阈值设置,设置超过多大值时直接在老年代进行分配。

超过这个值之后,就不会在新生代去创建,直接进行入老年代

设置好上述参数,然后执行下面程序:

image-20200219112038982

但是:并不是上面的参数结论的作用。所以,一般结论正确与否,还是需要通过代码来确定正确性。

是因为:上述概念是需要使用 Serial 垃圾回收器。

所以再加一个参数:-XX:+UseSerialGC设置项目启动之后使用的GC是Serial垃圾回收器

image-20200219113314931

老年代占用5M:直接就是程序定义的对象的大小:说明直接进入老年代。

使用可视化工具查看垃圾回收

image-20200219114409701

这里可视化工具提供的手动按钮是 Full GC (System.gc())

image-20200219114515452

image-20200219114528973

关于System.gc()的补充,我们手动调用gc或者自己执行gc方法的时候,我们只是告诉了JVM需要执行垃圾回收,但是至于什么时候回收,是由JVM决定的。

如果我们不告诉JVM需要GC的话,只有在创建新的对象的时候才有可能去校验是否需要垃圾回收。因为只有在创建对象的时候会导致堆内存的增加。

这就是System.get()方法存在的意义和价值:在没有对象创建的时候触发垃圾回收。

jmc查看的可视化

image-20200219114902217

image-20200219115251845

FromSurvivor和ToSurvivor的角色的切换

如果频繁切换,那么会通过一定的算法转移到老年代。

-XX:MaxTenuringThreshold=5:在可以自动调节对象晋升(Promote)到老年代阈值的GC中设置该阈值的最大值。

设置可以晋升到老年代的最大存活年龄。该参数的默认值为15,CMS中默认值为6,G1中默认为15(在JVM汇总,该数值是由4个bit来表示的,所以最大值为1111,即15)

-XX:+PrintTenuringDistribution:打印出年龄为n的字节对象

经历了多次GC后,存货的对象会在FromSurvivor和ToSurvivor的角色之间来回切换。而这里面的一个前提则是这两个空间有足够的大小来存放这些数据,在这些算法中。会计算每个对象年龄的大小,如果达到某个年龄后发现总大小已经大于了Survivor空间的50%,那么这时候就需要调整阈值,不能再继续等到默认的15此GC后才完成晋升,因为这样会导致Survivor空间不足,所以需要调整阈值,让这些存货对象尽快完成晋升。

Survivor空间不足是很严重的。

image-20200219121330920

image-20200219121345626

运行结果:

image-20200219121422183

threshold的动态调整

image-20200219130642857

image-20200219130751220

这个时候运行,没有问题。

接下来添加JVM参数

XX:TargetSurviorRatio=60 :占据百分之60,会重新计算阈值

XX:+PrintGCDateStamps:打印JVM运行的时间戳

XX:+UseConcMarkSweepGC: 老年代使用CMS

XX:+UserParNewGC:新生代使用ParNew

XX:MaxTenuringThreshold=3:最大年龄为3,就得去老年代了

image-20200219131136864

运行结果

image-20200219131207830

image-20200219132004058

image-20200219132049706

这里,下面的图,只有age=1的,说明,age=1,=2,=3的已经被全部放入老年代当中。

image-20200219131906826

枚举根节点

image-20200219154558522

OopMap数据结构

安全点: Safepoint

image-20200219154756567

Security Point : program execution can not stop at all the places down beginning GC, only when it reaches a safe point to pause.

image-20200219154809669

image-20200219155750717

Steals type interrupts: JVM interrupt

Active Break: polling place signage and safety point coincide. Now they interrupt themselves.

image-20200219160034945

Security Zone

image-20200219160331233

image-20200219161026460

Safe Region

CMS garbage collector Detailed

After the CMS garbage collector finish school, you need big efforts to learn about the G1 garbage collector.

Story: CMS study of people left, how new people can not read the C ++ source code.

CMS: Concurrent Mark Sweep Concurrent Mark Clear

image-20200219162027113

Concurrent meanings: garbage collection thread can simultaneously execute business users and thread.

Mark and clear: Description CMS is the use of mark and sweep to complete.

Flags: Flags is an object which is still part of a viable state. What is the need to clear the object.

Clear: Clear objects away garbage.

image-20200219162510850

Initial Tags:

Concurrent mark:

Relabeled: part due to the correction period concurrent user threads continue to operate a result of changes.

Concurrent clear:

CMS collector operational steps:

image-20200219162739106

The initial mark: STW, no user thread

Concurrent mark: Users can simultaneously execute and thread

Relabeled: STW, no user mark

Concurrent cleanup: Users can simultaneously execute and thread

Reset thread: return to the initial state

Advantages and disadvantages of CMS collector

advantage:

image-20200219163126923

Pause: it refers to the user thread pause

Disadvantages:

image-20200219163151757

Space allocation guarantees : the new generation can not accommodate, direct throw old's, which is called the old year guarantee.

image-20200219163505962

CMS collector collects steps:

image-20200219163917024

Without Concurrent, will lead the user to pause a thread

image-20200219164301754

image-20200219164418340

image-20200219165516791

image-20200219165709071

image-20200219165754883

image-20200219165840708

To this: Mark Complete. The next call to clean up the algorithm.

image-20200219165907894

image-20200219165926941

image-20200219165958257

image-20200219170028823

Program to recognize CMS garbage collector

code

image-20200219174208582

Virtual machine parameters

image-20200219174226957

operation result:

image-20200219174525991

Guess you like

Origin www.cnblogs.com/bigbaby/p/12348968.html
Recommended