文章导读:

从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用, 本章内容介绍了Reference的概念和语法实现. 附件有源码下载

视频与源码下载:http://edu.51cto.com/lecturer/index/user_id-9166337.html  (代码在视频的附件中)

强引用(StrongReference) :

强引用是使用最普遍的引用. 如果一个对象具有强引用, 那垃圾回收器绝不会回收它,当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止, 也不会靠随意回收具有强引用的对象来解决内存不足的问题

 public class RefDemo {

 // 强引用, JVM -Xms5M  -Xmx10M
public static void demo01(){
// 强引用,即使内存溢出,垃圾回收也不会回收此对象
byte[] b = new byte[1024*1024*10]; // 默认创建10MB的byte数组
}
}

为了方便测试首先要在JVM中配堆内存大小如图所示:

我们声明的 byte[] b = new byte[1024*1024*10] 是强引用类型,及时内存溢出GC也不会回收强引用的对象, 因此会抛出堆内存溢出

软引用(SoftReference):

软引用是除了强引用外, 最强的引用类型. 可以通过SoftReference使用软引用. 一个持有软引用的对象,不会被JVM很快回收. JVM会根据当前堆的使用情况来判断何时回收. 当堆的使用率接近临界点时, 才会去回收软引用的对象. 只要有足够的内存, 软引用变可以在内存中存货很长时间.因此, 软引用可以用于实现对内存敏感的cache

     // 软引用: 内存不够才会被回收,项目中的缓存
public static void demo02(){
MyObject myO=new MyObject();
// 采用软引用存储
SoftReference<MyObject> softRef=new SoftReference<MyObject>(myO);
myO = null; //强引用已经失效
// 手动调用垃圾回收,一般JVM自动调用
System.out.println(softRef.get());
System.gc(); // 如果内存足够,软引用是不会被回收的
System.out.println(softRef.get());
// 不断的填充堆空间,如果内存不够则回收
List<Object> oList=new ArrayList<Object>();
for(int i=1;i<=10;i++){
// 每次填充1MB
oList.add(new byte[1024*1024*1]);
System.out.println("当前虚拟机中的内存总量" + Runtime.getRuntime().totalMemory()/1024.00/1024 + "MB");
System.out.println("i:" + i);
// 软引用: 内存不够才会被回收
System.gc();
}
}

从运行结果我们可以看出, GC在内存不充足的时候才会回收软引用的空间. 但是回收的空间也不足以存储生成的数组对象,因此还是抛出了堆内存溢出

弱引用 (WeakReference):

弱引用是一种比软引用较弱的引用类型, 在系统GC时, 只要发现弱引用, 不管系统堆空间是否足够, 都会将对象进行回收. 但是由于垃圾回收器的线程通常优先级很低. 因此, 并不一定能很快发现持有的弱引用的对象. 在这种情况下. 弱引用对象可以存在较长时间.

 public class MyObject {
@Override
public String toString() {
return "I am MyObject";
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("MyObject's finalize called"); // 被回收时输出
}
public static void main(String[] args) throws InterruptedException {
MyObject obj = new MyObject();
WeakReference<MyObject> softRef = new WeakReference<MyObject>(obj); // 创建一个引用队列
System.gc(); // 因为还有强引用因此不能回收,一般在生产者模式下不会手动调用垃圾回收方法
System.out.println("获取弱引用:" + softRef.get());
obj = null;
System.gc(); // 无论空间是否充足都应该回收弱引用对象
}
}

我们会发现弱引用的对象,只要GC调用则就会被回收

Java强、软、弱引用总结:

最新文章

  1. 译:什么是ViewData的, ViewBag和TempData? - MVC为当前和后续请求之间传递数据的三种方法
  2. eclipse/MyEclipse 日期格式、注释日期格式、时区问题[转]
  3. Oracle 通过sql profile为sql语句加hint
  4. Blot消息处理者
  5. C# using
  6. U盘安装Centos后拔除U盘无法启动问题解决方法
  7. mysql基础篇 - SELECT 语句详解
  8. HBuilder git使用-建立仓库,邀请用户
  9. TypeError: format string
  10. 一个完整的hadoop程序开发过程
  11. JavaScript 基础,登录前端验证
  12. $.contains(a,b)
  13. appium自动化测试实战
  14. NIO 之 ByteBuffer
  15. 使用Maven部署构件至私服
  16. springboot-26-springboot 集成rabbitmq
  17. Going Home(最小费用最大流)
  18. C++进阶训练——停车收费系统设计
  19. MvvmLight - ViewModelLocator
  20. PokeCats开发者日志(十三)

热门文章

  1. Dubbo封装rest服务返回结果
  2. js获取当前的年月日时分秒周期
  3. Android(java)学习笔记137:ListView编写步骤(重点)
  4. xshell5 上传下载命令
  5. alibaba druid监控页面的使用配置
  6. linux - mysql 安装教程
  7. ES6 -- 模板字符串(反单引号)
  8. 自然数的拆分(DFS)
  9. 01、Linux介绍
  10. Python爬虫系列-PyQuery详解