引用计数算法--深入理解JVM内存结构,熟练GC垃圾回收机制,可以进行简单的JVM调优

本文介绍了引用计数算法及其在解决对象可达性问题上的局限,以及Java内存管理中的四种引用类型(强引用、软引用、弱引用和虚引用)及其应用场景。特别强调了强引用可能导致内存泄漏的问题和弱引用、虚引用在内存回收中的角色。
摘要由CSDN通过智能技术生成

                                引用

引用计数算法

枚举根节点做可达性分析

方法区的回收

强引用

软引用

弱引用

虚引用

引用(绳子)
        引用计数算法

        原理:给对象中每一个对象分配一个引用计数器,每当有地方引用该对象时,引用计数器的值加一,当引用失效时,引用计数器的值减一,不管什么时候,只要引用计数器的值等于0了,说明该对象不可能再被使用了。就会被回收(GC)     绳子计数器被绳子套上了就加个一

        优点:实现原理简单,而且判定效率很高。大部分情况下都是一个不错的算法。

        缺点:很难解决对象之间相互循环引用的问题,例如:对象A和对象B都有instance字段,并且A.instance=B,并且B.instance=A,即使这两个对象再无任何其他引用,并且已经不可能再被访问,引用计数器的值也为0了,这两个对象也是不可能再被使用了,此时引用计数器算法也无法通知GC来回收这两个对象   (类比死锁)

枚举根节点做可达性分析

四种GCRoots对象:

1、虚拟机栈(栈帧中的局部变量区)

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

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

4、本地方法栈JNI引用的对象

方法区的回收

        垃圾收集主要回收两部分内容:废弃常量和无用的类 回收废弃常量与回收Java堆中的对象非常类似。以常量池中字面量的回收为例,假如一个字符串“abc”已经进入了常量池中,但是当前系统没有任何一个String对象是叫做“abc”的,换句话说是没有任何String对象引用常量池中的“abc”常量,也没有其他地方引用了这个字面量,如果在这时候发生内存回收,而且必要的话,这个“abc”常量就会被系统“请”出常量池。

        判定一个类是否是无用类,需要满足三个条件:

1、该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。

2、加载该类的ClassLoader已经被回收。

3、该类对应的java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

强引用

编写的代码95%都是强引用

        默认支持 百分之九十五都是强引用,当内存不足,JVM开始垃圾回收 ,对于强引用的对象,就算是抛出OOM,也不会对该对象进行回收。强引用是造成Java内存泄露的最主要原因之一。

        对于一个普通对象,如果没有其他引用关系,只要超过了引用的作用域(局部变量)或者显示的将相应的引用赋值为null,一般就认为可以被垃圾收集了。

软引用

        内存充足 不回收,内存不足 回收。

        需要用java.lang.ref.SoftReference类实现 一般用来做(JVM中缓存)缓存 内存够用 不回收 不够用就回收

使用场景:

假如一个应用需要读取大量的本地图片:

  • 如果每次读取图片都从硬盘读取,则会严重影响性能

  • 如果一次性全部加载到内存中,有可能造成内存溢出

此时,可以使用软引用解决这个问题 够就存再内存只有内存不够时才会回收

弱引用

        在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。需要用java.lang.ref.WeakReference类实现

谈谈WeakHashMap的理解。

        map的toString方法会转为{1=hello world}

        `System.out.println(map)`输出`{1=hello world}`是因为`map`对象的`toString()`方法被调用了。

        在Java中,当我们直接将一个对象传递给`System.out.println()`方法时,实际上会调用对象的`toString()`方法将其转换为字符串进行输出。对于`Map`对象来说,`toString()`方法会按照`{key1=value1, key2=value2, ...}`的格式将其内容转换为字符串。

        在你的例子中,`map`对象是一个`Map<Integer, String>`类型的对象,其中键`1`对应的值是`hello world`。

        WeakHashMap(弱哈希map),只要一起用GC垃圾回收,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

虚引用

referenceQueue.poll() 回收站的放与拿

         “虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

        虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue回收站)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

                                                                                                        不足溢出oom,强引用会导致泄露

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值