Java中的各种引用(强引用、软引用、弱引用、虚引用)(二)

前言

Java中的各种引用(强引用、软引用、弱引用、虚引用)(一)里面已经说过了对象的创建和内存的分布,也提到了四种引用,这里说一下强引用

强引用

强引用就是一般的对象引用。被强引用的对象,只有在完全没有任何引用的时候,才会被系统回收。只要该对象存在引用,系统宁可抛出OOM,也不会强制回收该对象。

举例

准备

首先,需要对JVM的运行环境做一下设置,我们可以设置JVM的内存为20M,以方便观察。

-Xms20M -Xmx20M
测试
package com.test.application;

public class StrongReferences {

    public static void main(String[] args) throws InterruptedException {
        //Create a byte array, size is 13M
        byte[] big1 = new byte[13 * 1024 * 1024];
        System.out.println(System.currentTimeMillis() + ": " + big1);
        //Start the gc and wait 1s
        System.gc();
        Thread.sleep(1000);
        System.out.println(System.currentTimeMillis() + ": " + big1);
        //Create another byte array, size is 7M
        byte[] big2 = new byte[7 * 1024 * 1024];
        System.out.println(System.currentTimeMillis() + ": " + big2);
    }
}

输出结果:

1603957724013: [B@140e19d
1603957725021: [B@140e19d
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.test.application.StrongReferences.main(StrongReferences.java:14)

从结果可以看出,尽管触发了GC,但是内存空间并没有释放。如果需要释放,需要将big1的引用对象置为null(是否在GC前后没有关系,JVM有自己的垃圾回收,**System.gc()**只是强制触发一次垃圾回收)。

说明

在JVM参数中添加**-XX:+PrintGC**,可以查看JVM内存的垃圾回收日志信息。

-Xms20M -Xmx20M -XX:+PrintGC

运行结果:

1603957755744: [B@140e19d
[GC (System.gc())  14989K->14028K(19712K), 0.0008208 secs]
[Full GC (System.gc())  14028K->13937K(19712K), 0.0042578 secs]
1603957756750: [B@140e19d
[Full GC (Ergonomics)  14270K->13967K(19712K), 0.0038843 secs]
[Full GC (Allocation Failure)  13967K->13952K(19712K), 0.0035177 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.test.application.StrongReferences.main(StrongReferences.java:14)

可以看到,当创建对象 new byte[7 * 1024 * 1024] 的时候,JVM已经没有足够的内存了。此时,对于第一个对象new byte[13 * 1024 * 1024] ,仍然存在内存中,没有被回收掉。此时,JVM只能抛出OOM异常。

添加一个将big1的指向置为null的操作后,在查看运行结果

        ···
        System.gc();
        big1 = null;
        Thread.sleep(1000);
        ···

运行结果:

1603958096674: [B@140e19d
[GC (System.gc())  14876K->14076K(19712K), 0.0008062 secs]
[Full GC (System.gc())  14076K->13936K(19712K), 0.0051718 secs]
1603958097681: null
[Full GC (Ergonomics)  14243K->655K(19712K), 0.0054385 secs]
1603958097687: [B@17327b6

big1置为null之后,对象new byte[13 * 1024 * 1024] 失去所有引用,此时,被回收,JVM有足够的内存空间来创建对象 new byte[7 * 1024 * 1024]

结论

强引用是最常见的引用,但是对内存的需求很大。当存在太多的强引用对象时,JVM可能会抛出OOM异常。在实际的使用中,建议对已经使用结束的引用做null处理,以减少对内存的占用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值