黑马JVM总结(十一)

(1)垃圾回收概述

前面我们学了堆,里面有一个垃圾回收的机制 

黑马JVM总结(十一)_第1张图片

(2)判断垃圾_引用计数

指只要有一个对象被其他变量所引用,我们就让这个对象的计数加1,有个一变量不在引用,让它的计数减一,当这个对象的计数变为0的时候,说明没有变量引用它了,那么他就可以作为一个垃圾进行一个回收,但是引用计数存在一个弊端:存在循环引用问题:

a对象引用b对象,b对象的引用计数为1。b对象引用a对象,a对象的引用计数为1,但是没有谁用再引用他们啦,是不是以为这他们俩可以被垃圾回收呢了,答案是不行,因为他们的引用计数都为1虽然这两个对象都不会再使用了他们的引用计数不能归零导致不能被垃圾回收,造成了内存上的泄露

派森虚拟机采用的是这种算法但是我们Java虚拟机既不会采用这种算法:而是采用可达性分析

黑马JVM总结(十一)_第2张图片

 (3)判断垃圾_可达性分析_根对象

可达性分析呢需要首先确定一系列根对象,根对象是哪些肯定不能别当做垃圾的对象,我们称之为根对象,在垃圾回收之前我们会对堆内存中的所有对象进行一遍扫描,看看每一个对象是不是刚才提到的根对象所直接或者间接引用,如果被直接或间接的引用过,就不能被回收

黑马JVM总结(十一)_第3张图片

通过一个工具可以查看根对象:

黑马JVM总结(十一)_第4张图片

黑马JVM总结(十一)_第5张图片

MAT工具需要跟jmap工具一起使用 ,MAT需要jmap工具配合jmap先把内存快照抓取下来,才能使用MAT工具进行进一步分析

使用jps:查看一下进程id:

黑马JVM总结(十一)_第6张图片 

先需要使用jmap工具把内存快照抓取下来,转储成一个文件:dump文件的参数=b为二进制,live:为抓取哪些存货的对象,live在抓取之前进行一个垃圾回收,file:抓取的的内存快照 存成一个文件

黑马JVM总结(十一)_第7张图片

黑马JVM总结(十一)_第8张图片

执行到2再抓取一下,存为另外一个文件:

黑马JVM总结(十一)_第9张图片

打开MAT工具:选择抓取的快照文件:

黑马JVM总结(十一)_第10张图片

黑马JVM总结(十一)_第11张图片

有一个显示图:对内存占用多的对象有哪些

黑马JVM总结(十一)_第12张图片

还可以查看抓取的快照的根对象有哪些 

黑马JVM总结(十一)_第13张图片

分为以下类: 

黑马JVM总结(十一)_第14张图片

(1)System Class:系统类,是由启动类加载器加载的类,核心的类,

黑马JVM总结(十一)_第15张图片

(2)java虚拟机在执行一些方法调用时去调用操作系统的方法,操作系统方法在执行时所引用的一些java对象,也是可以作为根对象 

 黑马JVM总结(十一)_第16张图片

一些活动线程:活动线程中正在使用的一些对象不能当做垃圾的

线程运行时由一个个的方法调用组成,每次方法调用嫩都会产生一个栈帧,栈帧内所使用的一些东西可以作为根对象

黑马JVM总结(十一)_第17张图片

 主线程内:栈帧内用到的变量的情况,他们用到的一些局部变量,这些局部变量所引用的对象,都可以作为根对象,局部变量时存在栈帧里的new 的对象是存在堆里的,根对象是指堆中的哪些对象而不是栈帧里的局部变量引用

比如代码中创建的ArrayList集合对象

黑马JVM总结(十一)_第18张图片

 

(3)Java对象中有个同步锁机制,Syschorlnize关键字如果对一个对象加了锁,被加锁的对象不能被当做垃圾的,正在加锁的对象作为根对象

黑马JVM总结(十一)_第19张图片

 第二个存储文件:

黑马JVM总结(十一)_第20张图片

当19行list局部变量为null ,不在应用ArrayList对象了,因为我们执行了jamp:里面有live参数,它会主动执行一次垃圾回收,它会把不在引用改的Arraylist对象回收掉了,所以在根对象列表中就没有ArrayList对象了

黑马JVM总结(十一)_第21张图片 

你可能感兴趣的:(JVM虚拟机,jvm)