jvm(java虚拟机垃圾清理机制流程)

首相我们要知道jvm的一个内存图:

上图就是虚拟机的内存图:

内存区域分为本地方法栈、虚拟机栈、堆、程序计数器、方法区等,方法区又被称作永久代。

栈区的底部是先执行的主线程,每个栈去多是一个线程,所以在报错的时候我们可以到如下图的一个报错信息顺序!

从上图我们可以看到主线程main方法是在最下面的,其他的相关的执行线程多是在上面的!这个只是一个栈去的一个内存理解!

下面讲下jvm怎么找到垃圾并且清理垃圾!

因为java版本的不同jvm内部有些东西也会改变,比如一些永久代报错信息的不同有兴趣了解不同版本jvm的一个内存报错信息的

可以打开这个连接看下,https://blog.csdn.net/dingpiao190/article/details/72831125

个人见解,要想理解清jvm的内存和清理机制建议是手写一个jvm虚拟机,附上个人觉得不错的书籍,

jvm的皇帝就是gc它负责回收垃圾它还有一个别称叫环卫个工人!

jvm以前的找垃圾的方法用的一个算法是:

1:引用技术法:

第一个对象被引用一次那么它的对象计数就+1,退出作用域那么就就减-1;

Object obj=new Object();//new Object();是一个对象,obj就是一个引用+1;

这个算法有一个缺点就是两个傻逼对象互相引用,但是程序中又没有使用这个2个傻逼对象,要是这种写法多了就会产生

内存泄露,内存泄露会在下面讲,

2.根搜索算法:

这个算法其实就是为了解决上面那种傻逼对象的一个存在,那么这个算法是怎么实现的呢?

1.虚拟机栈(栈帧中的本地变量表)中的引用对象。

2.方法区中的类静态属性引用的对象。

3.方法区中的常量引用的对象。

4.本地方法栈中JNI(也即一般说的Native方法)的引用的对象。

用太专业的词汇我一时描述不出!简单来讲就是上面这些去里面引用的对象,会产生一个跟路径,这个路径会把相关的

引用联起来,那么判断一个内存的资源是不是垃圾就是很简单了,想那种没有根的傻逼相互关联,就会被认定为垃圾了!

gc皇帝就会干掉它,

既然找垃圾有方法那么清楚垃圾肯定也有相关的方法!

1:标记清除法:

只要发现垃圾内存时,标记为可回收的状态,等下一起干掉!

但是有个缺点就让人很受不了,清理的内存空间多是零碎的,哪么当程序需要内存时就会遇到一个很尬尴的事情,我需要一个5M的内存,你清理的这个小地方只有3M那么放不下啊!那么的改进方法啊!

2:分段复制算法:

 上图是分段复制算法的一个处理前后图!

复制算法原理  :

Survivor区,一块叫From,一块叫To,对象存在Eden和From块。当进行GC时,Eden存活的对象全移到To块,而From中,存活的对象按年龄值确定去向,当达到一定值(年龄阈值,通过-XX:MaxTenuringThreshold可设置)的对象会移到年老代中,没有达到值的复制到To区,经过GC后,Eden和From被清空。

 之后,From和To交换角色,新的From即为原来的To块,新的To块即为原来的From块,且新的To块中对象年龄加1.

疑问:

只分一块Survivor区,当进行GC时,先将Survivor区中存活的对象达到年龄值的移入年老代,清除已死亡的对象,后将Eden区中存活的对象移入Survivor区,将Survivor区的对象年龄都加1.这样与分两块Survivor有什么区别呢,为什么虚拟机一定要分成两块呢?

即若只分一块Survivor,在清除Survivor区已死亡的对象时,因为此刻的Survivor区还有存活的对象,清除要比分两块Survivor麻烦,两块的情况,回收时只需将存活的对象移走,剩下的对象直接清理即可。

另外,分成两块Survivor,From和To分工明确,逻辑理解和技术实现较简单

     3:标记整理算法:
        于分段复制差不多!
    4:分代收集法1:(方便管理)
        新建的对象称为新生代,当被回收几次后便分化为老年区(经过几次回收后一直在使用),如果老年区又再过n次回收便划分为永久代
        新生代扫描频率高,老年区小,永久代是频率最低(目的是提高性能)
   现在的jdk基本多是使用这个!

6:内存泄漏
    本该被回收的内存,遗漏了,一直占用(程序运行一段时候后很卡有可能就是内存泄漏了)
7:内存溢出
    分配给进程的内存满了
    我们可以设置这个程序的内存最小多少内存,最大多少内存
    堆内存溢出:
        7.1.堆内存溢出:
            OutOfMemoryError: Java heap space
        7.2.方法区(永久代)溢出:
            OutOfMemoryError: Metaspace
        7.3.栈内存溢出:
            StackOverflowError 

猜你喜欢

转载自blog.csdn.net/weixin_41244495/article/details/82261022
今日推荐