之前在看深入理解Java虚拟机一书中第一次接触相关名词,但是并不理解,只知道Object obj = new Object()类似这种操作的时候,obj就是强引用。强引用不会被gc回收直到gc roots不可达时。而对其他三个名词并不清楚,因为并没有被真正使用过。通过查看软引用,弱引用和虚引用的源码,可以看出这三个类都是继承自Reference。

一 概念

1.1软引用(SoftReference)

我理解的软引用的意思是,即使引用对象没有被使用了,gc也不会马上回收,而是只有当堆内存空间不够时才会回收。一般用于缓存对象,因为希望在内存中保留的越久越好。软引用所指向的引用对象停留在堆内存的时间由当前可用堆内存的大小来控制。软引用中有两个字段:clock和timestamp。clock记录初始化或gc的时间,而get引用对象时会更新timestamp与clock时间一致。如果clock和timestamp的间隔时间超过maxInternal,则认为该引用对象很久没有使用是时候回收该引用对象,否则会继续存在。maxInternal的时间有当前可用堆内存大小决定。具体jvm源码可以参考:https://mp.weixin.qq.com/s/pPXNeUI57GD-YnnfQWGXbg

1.2弱引用 (WeakReference)

弱引用的意思是如果引用对象gc roots不可达,gc就会进行回收。get操作可能返回引用对象(如果没有gc),否则返回空。

1.3虚引用 (PhantomReference)

虚引用不能返回引用对象,因为get操作返回的一直是null,感觉就是一个虚无缥缈的引用,所以这是称之为虚引用的原因吧。

二 实例

构造一个对象TestObj,它的大小为1M对一点。

JVM参数设置:

-Xms8M 初始堆大小

-Xmx8M 堆的最大值

-Xmn4M 年轻代的大小

-XX:+PrintGCDetails

-XX:SurvivorRatio=8 eden:survivor的比列为8:1

第一种情况:

gc过程:

分析:

Eden:3072k, from:512k, to:512k, ParOldGen:4096k

调用System.gc的时候对象强引用还存在,所以三个引用对象会进入到老年代。

第二种情况:

gc过程:

分析:

由于此时年轻代不能再分配一个1M多的空间,而老年代也放不下,所以会发生full gc, 弱引用和虚引用的对象会被回收,而软引用还存在。cost[0],cost[1]进入老年代,而此时年轻代应该只有一个cost[2]对象,为什么会占据eden:3072k空间的69%呢,这让人很疑惑???

第三种情况:

gc过程:

分析:

由于eden:3072k的空间已经被使用了69%,所以不能在放下一个1M的对象,只能full gc(当准备要触发一次young GC时,如果发现统计数据说之前young GC的平均晋升大小比目前old gen剩余的空间大,则不会触发young GC而是转为触发full GC。full gc 和 young gc关系参考:https://www.zhihu.com/question/41922036/answer/93079526),所以软引用所指对象被最终收回。果然软引用存活时间够长,只有堆内存足够。

java中的强引用(Strong reference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)的更多相关文章

  1. 【Java思考】Java 中的实参与形参之间的传递到底是值传递还是引用传递呢?

    科普: 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数. 引用传递(pass by reference)是指在 ...

  2. Java中的强引用,软引用,弱引用

    作者:winterSunshine链接:https://www.zhihu.com/question/37401125/answer/100981172来源:知乎著作权归作者所有.商业转载请联系作者获 ...

  3. java中的强引用、软引用、弱引用、虚引用

    1.强引用(Strong Reference):指程序代码中普遍存在的,类似“Object obj = new Object()”这类的引用,只要对象存在强引用关联,JVM必定不会回收这个对象: 2. ...

  4. java中的强,软,弱,虚引用

    引用的应用场景 我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型.这正是Java中弱引用和软引用的主要区别. 如果一个对象只有弱引用指向 ...

  5. java 中 Cannot make a static reference to the non-static 解决方法

    今天敲代码的时候遇到了这个问题,大体这个问题可以简化成这样: public class Test1 { public String get() { return "123"; } ...

  6. Java中的强引用和弱引用

    旭日Follow_24 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/xuri24/article/details/81114944 一.强引用 如下是强引用的经典 ...

  7. java中list强转为map类型

    起因:读取数据库文件的测试用例,测试用例需要存放到一个map中,方便下次调用, 读取的内容返回的内容存放在一个list中,并且数据内容是key=value的形式,最开始使用切片方式,做了很多无用功,后 ...

  8. Java中弱引用、软引用、虚引用及强引用的区别

    Java中弱引用VS软引用 Java中有如下四种类型的引用: 强引用(Strong Reference) 弱引用(WeakReference) 软引用(SoftReference) 虚引用(Phant ...

  9. Java中的四种引用(强引用、软引用、弱引用、虚引用)

    以下内容摘自<深入理解Java虚拟机 JVM高级特性与最佳实践>第2版,强烈推荐没有看过的同学阅读,读完的感觉就是"原来学的都是些什么瘠薄东西(╯‵□′)╯︵┴─┴" ...

随机推荐

  1. dcoker 搭建单节点redis

    1.安装docker 1.检查内核版本,必须是3.10及以上 [root@localhost ~]# uname -r 2.安装docker [root@localhost ~]# yum insta ...

  2. 基于flask的python注册到eureka

    Eureka架构中的三个核心角色: 服务注册中心 Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的eureka-demo 服务提供者 提供服务的应用,可以是SpringBoot应用 ...

  3. Centos7中MySQL8.0安装过程及遇到的问题记录

    本文主要参考以下2篇文章,安装操作 https://www.miboxapp.com/article/detail/1146659339214393344 https://blog.csdn.net/ ...

  4. python测试报告输出 htmltestrunner 及 中文乱码的解决方式

    下载HTMLTestRunner.py 第三方库 下载地址: python2:http://tungwaiyip.info/software/HTMLTestRunner.html 右键另存为下载HT ...

  5. CF1137A/1138C Skyscrapers

    排序+数据结构 将每一行(每一列)都排个序,并将原位置的在这一行(列)中的排行记录在一个数组里 注意,要将楼高度相同的元素看作一个元素 如 1 1 4 5 6 8 8,则排行是      1 1 2 ...

  6. MySQL中load data infile将文件中的数据批量导入数据库

    有时候我们需要将文件中的数据直接导入到数据库中,那么我们就可以使用load data infile,下面具体介绍使用方法. dao中的方法 @Autowired private JdbcTemplat ...

  7. 错误C3646“name”: 未知重写说明符 问题

    在用多文件编译来写一个程序时,遇到了一个错误: 错误C3646"name": 未知重写说明符 于是我就去某搜索引擎上搜索一下前辈们对这个错误的心得 综合网上的经验我总结了一下出现这 ...

  8. 【SpringCloud】02.微服务与SpringCloud

    微服务的特点 一系列微小的服务共同组成 跑在自己的进程里 每个服务为独立的业务开发 独立部署 分布式管理 异构--不同的语言.不同类型的数据库 微服务架构的基础框架/组件 服务注册发现 服务网关(Se ...

  9. ubuntu下安装国际版QQ

    在网上看到了好多的ubuntu下安装QQ的方法 好多 下面是看别人的文章 来测试的一篇 ubuntu下 安装国际版QQ http://www.ubuntukylin.com/applications/ ...

  10. C# 8: 可变结构体中的只读实例成员

    在之前的文章中我们介绍了 C# 中的 只读结构体(readonly struct)[1] 和与其紧密相关的 in 参数[2]. 今天我们来讨论一下从 C# 8 开始引入的一个特性:可变结构体中的只读实 ...