zoukankan      html  css  js  c++  java
  • (2) JVM内存管理:垃圾回收

    回顾上期

    1)JVM中引用存在哪里?

    答:虚拟机栈,该内存空间线程独有

    2)该引用的对象存在哪里?

    答:堆,所有通过new方法分配的对象都存在堆中

    3)String s1="abc",字符串"abc"存在哪里?
    答:运行时常量池,且常量池每次存储对象时会查找是否存过相等的对象,如果有,直接引用指向它,不再开辟空间。

    如果你三个问题都可以回答出来,恭喜你!上一篇的精髓你get到了~~~~

    引用的分类

    1) 强引用,默认分配方式均为此类型

    Object a=new Object();


    2) 软引用,以强引用为参数,构造弱引用

    Object a=new Object();
    SoftReference<Object> b=new SoftReference<Object>(a);
    a=null; //强引用a一定要断掉
    System.out.println(b.get()); //通过get()方法返回对象 


    3) 弱引用

    Object a=new Object();
    WeakReference<Object> b=new WeakReference<Object>(a);
    a=null; //强引用a一定要断掉
    System.out.println(b.get()); //通过get()方法返回对象
    System.gc();


    4)幽灵引用,和没有引用是一样的

    引用的特点

    1)有强引用指向的对象不会被垃圾回收

    2)软引用指向的对象在堆的空间不够时被回收

    3)只要系统执行垃圾回收,就会回收软引用

    从上面三点中,我们总结出垃圾回收是也是JVM中的一个线程,每执行一次,都要检查对象有没有强引用指向

    如果没有再依次考虑软引用和弱引用

    那么怎么检查呢?

    代码分析

    垃圾回收检查算法

    1) 计数分析

    每个对象,都给一个计数器,每增加一个强引用,就把计数器+1,如果当前计数器的值为0,就回收

    思路很简单,但是会发生问题

    Object a = new Object(); // a的引用计数为1
    Object b = new Object(); // b的引用计数为1
     
    a.next = b; // b的引用计数为2
    b.next = a; // a的引用计数为2
     
    a = null; // a的引用计数为1,尽管已经显示地将a赋值为null,但是由于引用计数为1,GC无法回收a
    b = null; // b的引用计数为1,同理,GC也不回收b


    2) 可达性分析

    从GC Root往下搜索,如果该对象是可达的,找到到达该对象的最短路径

    最短路径中的强度最弱的引用,决定了该对象是否被回收,如:

    GC Root-(弱引用)->1对象-(强引用)->5对象

    那么上述两个对象都是要被回收的

    另外:GC Root 是什么?一些特殊的对象

    虚拟机栈(栈帧中的本地变量表)中引用的对象,往往是方法中的一些简单类型变量

    方法区中类静态属性引用的对象
    方法区中常量引用的对象

  • 相关阅读:
    Linux环境下安装MySQL(解压方式)
    Linux环境下安装MySQL(yum方式)
    Linux环境下安装ActiveMq
    Linux环境下安装Tomcat
    Linux环境下安装JDK
    Linux就该这么学--命令集合6(打包压缩文件、文件查询搜索命令)
    Linux就该这么学--命令集合5(用户与组管理命令)
    Linux就该这么学--命令集合4(文件目录管理命令)
    Linux就该这么学--命令集合3(文本文件编辑命令)
    解决shell脚本“syntax error near unexpected token `fi'”的问题。
  • 原文地址:https://www.cnblogs.com/Plorde/p/12302234.html
Copyright © 2011-2022 走看看