Java中四种引用类型:强引用,软引用,弱引用,虚引用
四种引用类型
- 强引用(StrongReference)
- 软引用(SoftReference)
- 弱引用(WeakReference)
- 虚引用 (PhantomReference)
强引用
类似Object obj = new Object()这类似的引用,强引用在程序代码中普遍存在,只要强引用在,垃圾搜集器永远不会搜集被引用的对象。也就是说,宁愿出现内存溢出(OutOfMemoryError),也不会回收这些对象
在IDEA中EditConfigiratons中设置参数:-Xms20m 设置堆内存大小为20M
执行如下代码:
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
执行如下代码:
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());
}
}
}
输出结果
[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
执行如下代码:
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()+"---------");
}
}
输出结果:
[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类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
虚引用与软引用和弱引用的区别:虚引用必须和引用队列联合使用。
示例代码:
Object object = new Object();
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue);
- Silverlight 3.0 中的 Local Connection
- 学习Spark——那些让你精疲力尽的坑
- 学习Spark——那些让你精疲力尽的坑
- Silverlight 3.0 中的 WriteableBitmap
- WCF后续之旅(10): 通过WCF Extension实现以对象池的方式创建Service Instance
- Silverlight菜单控件 — CurveMenu
- 实力终端撑腰 两枚域名均五位数被秒
- Silverlight制作逐帧动画 v2 - part2
- Nodejs学习笔记(四)--- 与MySQL交互(felixge/node-mysql)
- 学习Spark——环境搭建(Mac版)
- 离线网络环境下一键式部署
- WCF后续之旅(17):通过tcpTracer进行消息的路由
- Linux同步机制(一) - 线程锁
- Silverlight类库介绍-FJCore
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 数据一致性校验及数据同步,运维必看
- Windows使用scoop包管理器安装RabbitMQ
- 深入理解web协议(二):DNS、WebSocket
- Elasticsearch:使用 function_score 及 soft_score 定制搜索结果的分数
- Elasticsearch:基于 Vector 的打分
- RocketMQ的发送模式和消费模式
- 实现一个简单的JS效果
- 1000000 / 60S 的 RocketMQ 不停机,扩容,平滑升级!
- Mysql支持远程链接访问
- linux shell编程
- Linux下的I/O复用与epoll详解
- 时间序列&日期学习笔记大全(上)
- LeetCode 题解:一顿操作猛如虎,一看击败百分五
- 这是什么沙雕题目?测试用例居然有人身高为 0 ??
- 深入解读flink sql cdc的使用以及源码分析