四种引用类型
- 强引用(StrongReference)
- 软引用(SoftReference)
- 弱引用(WeakReference)
- 虚引用 (PhantomReference)
强引用
类似Object obj = new Object()这类似的引用,强引用在程序代码中普遍存在,只要强引用在,垃圾搜集器永远不会搜集被引用的对象。也就是说,宁愿出现内存溢出(OutOfMemoryError),也不会回收这些对象
在IDEA中EditConfigiratons中设置参数:-Xms20m 设置堆内存大小为20M
执行如下代码:
代码语言:javascript复制package com.example.reference;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 演示强引用
* -Xmx20M
*/
public class StrongReference {
private static final int _4MB = 4 * 1024 * 1024;
public static void main(String[] args) throws IOException {
List<Byte[]> list = new ArrayList<>();
for (int i = 0; i <5 ; i ) {
list.add(new Byte[_4MB]);
}
System.in.read();
}
}
执行结果会异常Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
软引用
在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象
在IDEA中EditConfigiratons中设置参数:-Xmx20M -XX: PrintGCDetails
执行如下代码:
代码语言:javascript复制package com.example.reference;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
/**
* 演示软引用
* -XX: PrintGCDetails
*/
public class SoftReferenceTest {
private static final int _4MB = 4 * 1024 * 1024;
public static void main(String[] args) {
List<SoftReference<byte[]>> list = new ArrayList<>();
for (int i = 0; i < 5; i ) {
SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB]);
System.out.println(ref.get());
list.add(ref);
System.out.println(list.size());
}
System.out.println("-----------循环结束" list.size() "---------");
for (SoftReference<byte[]> ref : list) {
System.out.println(ref.get());
}
}
}
输出结果
代码语言:javascript复制[B@2cdf8d8a
1
[B@30946e09
2
[B@5cb0d902
3
[GC (Allocation Failure) [PSYoungGen: 5434K->491K(6144K)] 17722K->13790K(19968K), 0.0042190 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[Full GC (Ergonomics) [PSYoungGen: 491K->0K(6144K)] [ParOldGen: 13298K->13724K(13824K)] 13790K->13724K(19968K), [Metaspace: 3273K->3273K(1056768K)], 0.0129237 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
[B@46fbb2c1
4
[Full GC (Ergonomics) [PSYoungGen: 4208K->4096K(6144K)] [ParOldGen: 13724K->13585K(13824K)] 17933K->17681K(19968K), [Metaspace: 3274K->3274K(1056768K)], 0.0155442 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
[Full GC (Allocation Failure) [PSYoungGen: 4096K->0K(6144K)] [ParOldGen: 13585K->1279K(8704K)] 17681K->1279K(14848K), [Metaspace: 3274K->3274K(1056768K)], 0.0130777 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
[B@1698c449
5
-----------循环结束5---------
null
null
null
null
[B@1698c449
Heap
PSYoungGen total 6144K, used 4377K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
eden space 5632K, 77% used [0x00000000ff980000,0x00000000ffdc6400,0x00000000fff00000)
from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
ParOldGen total 8704K, used 1279K [0x00000000fec00000, 0x00000000ff480000, 0x00000000ff980000)
object space 8704K, 14% used [0x00000000fec00000,0x00000000fed3fcf0,0x00000000ff480000)
Metaspace used 3284K, capacity 4500K, committed 4864K, reserved 1056768K
class space used 352K, capacity 388K, committed 512K, reserved 1048576K
我们发现使用SoftReference软引用之后,并没有内存溢出(OutOfMemoryError)异常,并且遍历list发现前四个byte数组为null了,通过输出结果及GC详细信息我们可以验证出,对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象
弱引用
弱引用也是用来描述非必需对象的,用java.lang.ref.WeakReference类来表示,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
在IDEA中EditConfigiratons中设置参数:-Xmx20M -XX: PrintGCDetails
执行如下代码:
代码语言:javascript复制package com.example.reference;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
public class WeakReferenceTest {
private static final int _4MB = 4 * 1024 * 1024;
public static void main(String[] args) {
List<WeakReference<byte[]>> list = new ArrayList<>();
for (int i = 0; i < 5; i ) {
WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB]);
list.add(ref);
for (WeakReference<byte[]> w : list) {
System.out.print(w.get() " ");
}
System.out.println();
}
System.out.println("-----------循环结束" list.size() "---------");
}
}
输出结果:
代码语言:javascript复制[B@2cdf8d8a
[B@2cdf8d8a [B@30946e09
[B@2cdf8d8a [B@30946e09 [B@5cb0d902
[GC (Allocation Failure) [PSYoungGen: 5434K->507K(6144K)] 17722K->13757K(19968K), 0.0034897 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 507K->0K(6144K)] [ParOldGen: 13249K->1436K(13312K)] 13757K->1436K(19456K), [Metaspace: 3273K->3273K(1056768K)], 0.0109383 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
null null null [B@46fbb2c1
null null null [B@46fbb2c1 [B@1698c449
-----------循环结束5---------
Heap
PSYoungGen total 6144K, used 4321K [0x00000000ff980000, 0x0000000100000000, 0x0000000100000000)
eden space 5632K, 76% used [0x00000000ff980000,0x00000000ffdb86e0,0x00000000fff00000)
from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
ParOldGen total 13312K, used 5532K [0x00000000fec00000, 0x00000000ff900000, 0x00000000ff980000)
object space 13312K, 41% used [0x00000000fec00000,0x00000000ff1673e8,0x00000000ff900000)
Metaspace used 3282K, capacity 4500K, committed 4864K, reserved 1056768K
class space used 352K, capacity 388K, committed 512K, reserved 1048576K
Process finished with exit code 0
虚引用
java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
虚引用与软引用和弱引用的区别:虚引用必须和引用队列联合使用。
示例代码:
代码语言:javascript复制Object object = new Object();
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue);