java中强,软,弱,虚引用 以及WeakHahMap
一:强软引用:
package reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.WeakHashMap;
public class ReferenceObject {
public static void main(String[] args) {
//strongToSoft();
softReferenceToReferenceQueue();
}
/**
* 强引用转软引用
* 执行完代码1,可知Student这个对象被'变量'strongRef强引用
* 执行完代码2,可知Student这个对象被'SoftReference对象'softRef软引用
* 此时有两条引用引用路径(根据对象可及性的判断,单条引用路径取最弱的一个引用决定对象的可及性,多条引用路径取最强的一条的引用决定对象的可及性)
* 所以此时的Student对象为强引用
* 执行完代码3,只剩一条引用路径,所以此时是软引用的
* 执行完代码4,通过软引用对象的get方法把Student这个对象转回强引用给anotherStrongRef变量上
* 此时的anotherStrongRef变量引用的地址还是和之前strongRef变量的地址是一样的.其实strongRef,softRef,anotherStrongRef指向堆内存地址都是一样的
* 只不过softRef是在软引用对象里再引用了Student对象信息,即对象里包含对象
* 如果softRef因内存不足而回收之后,调用get()方法就只能得到null了。
*/
public static void strongToSoft(){
Student strongRef = new Student(1, "chenyong");// 1,强引用
System.out.println("最初的强引用:"+strongRef+",hashCode:"+strongRef.hashCode());
SoftReference<Student> softRef = new SoftReference(strongRef);// 2,软引用
strongRef = null;// 3
System.out.println("软引用:"+softRef);
Object anotherStrongRef = softRef.get();// 4
System.out.println("软引用转变的强引用:"+anotherStrongRef+",hashCode:"+anotherStrongRef.hashCode());
}
/**软引用对象到引用队列
* 代码2处创建一个引用队列,用于给到代码3的机构方法中,SoftReference的机构方法有2种,带队列的与不带队列的
* 此处加上引用队列,用于对软引用对象的引用对象因内存不足而清楚后把该软引用对象加入到引用队列中
* 即当强引用strongRef被清除后,软引用softRef因内存不足导致所引用的strongRef也被清除,最后把软引用本身softRef加入到引用队列
* 代码5处通过队列的poll()方法返回队列的第一个软引用对象
* 可以再代码6中对软引用对象进行清除
*/
public static void softReferenceToReferenceQueue(){
Student strongRef = new Student(2, "chenben");// 1,强引用
System.err.println("最初的强引用:"+strongRef+",hashCode:"+strongRef.hashCode());
ReferenceQueue queue = new ReferenceQueue<>();// 2,创建引用队列
SoftReference<Student> softRef = new SoftReference(strongRef,queue);// 3,添加引用队列的软引用
strongRef = null;// 4
System.err.println("软引用:"+softRef);
System.err.println("引用队列的第一个软引用对象:"+queue.poll());// 5
//利用队列消除软引用对象
SoftReference softObject ;
while((softObject = (SoftReference) queue.poll()) != null){
// 6 清除softObject
}
}
/**
* 在Java集合中有一种特殊的Map类型—WeakHashMap,
* 在这种Map中存放了键对象的弱引用,当一个键对象被垃圾回收器回收时,那么相应的值对象的引用会从Map中删除。
* WeakHashMap能够节约存储空间,可用来缓存那些非必须存在的数据。关于Map接口的一般用法。
*/
public static void useWeakHashMap(){
WeakHashMap map = new WeakHashMap();
}
}
二:WeakHahMap与弱引用
package reference;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
/**
* 普通HashMap和WeakHahMap区别
* @author t433
*
*/
public class WeakHashMapTest {
public static void main(String[] args) {
storeToOrdernaryMap();
storeToweakHashMap();
}
/**
* 普通HashMap存储数据时,存储的都是强引用类型的,并不会因为内存不足而回收对象
* 所以内存会因为不足导致 java.lang.OutOfMemoryError: Java heap space
* 在抛出异常前map存储的第一个数据都会一直存在,并不会清楚之前存储的数据
*
* 注:在代码1处i对后面的数字取模时,假如数字较小时,要导致OutOfMemoryError需要的时间更长,
* 因为数字较小时在单位时间内程序进入if里面执行打印的次数较多,而进行map存放的次数较小 ,所以需要更长的时间来执行map.put()
*
*/
public static void storeToOrdernaryMap(){
Map<String, String> map = new HashMap<String, String>();
long i = 1;
while (i < 100000000L) {
map.put(String.valueOf(i),"java-HashMap-java");
// 测试第一个是否依然存活
if (i % 100000 == 0) {// 1
System.out.println("第"+i+"次判断普通HahMap的第1个map的值:"+map.get(String.valueOf(1)));// 大概在 3000000次时抛出异常
}
i++;
}
}
/**
* WeakHashMap将弱引用作为内部数据的存储方案
* 弱引用不像 SoftReference 需要条件(软引用对象会在内存不足时被清理,但是内存充足情况下不会清除)
* WeakHashMap存储的是弱引用对象,当内存不足时会触发垃圾回收器清理,然后垃圾回收器会清除掉弱引用对象
*/
public static void storeToweakHashMap(){
Map<String, String> map = new WeakHashMap<String, String>();
long i = 1;
while (i < 100000000L) {
map.put(String.valueOf(i),"java-WeakHashMap-java");
// 测试第一个是否依然存活
if (i % 100000 == 0) {
System.out.println("第"+i+"次判断WeakHashMap第1个map的值:"+map.get(String.valueOf(1)));// 3000000
}
i++;
}
}
}
- java中的强,软,弱,虚引用
引用的应用场景 我们都知道垃圾回收器会回收符合回收条件的对象的内存,但并不是所有的程序员都知道回收条件取决于指向该对象的引用类型.这正是Java中弱引用和软引用的主要区别. 如果一个对象只有弱引用指向 ...
- 一道笔试题来理顺Java中的值传递和引用传递
题目如下: private static void change(StringBuffer str11, StringBuffer str12) { str12 = str11; str11 = ...
- java中的值传递和引用传递有什么区别呀?
值传递: (形式参数类型是基本数据类型和String):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参 ...
- Java 中的值传递和引用传递问题
Java 中的值传递和引用传递问题 public class Operation { int data = 50; void change(int data) { data = data + 100; ...
- (转)Java中的值传递和引用传递
Java中的值传递和引用传递 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值 ...
- Java中强、软、弱、虚引用
1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会回收它.当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使 ...
- java中的软,弱,虚引用介绍与特性分析
java的弱,虚,软引用介绍 1.弱,虚,软引用的介绍 对于绝大部分的对象而言,在程序中是存在着一个引用变量引用该对象,这是常见的引用方式,也就是常说的 强引用,对于强引用引用的对象,系统JVM是不会 ...
- Java中的软引用、弱引用、虚引用的适用场景以及释放机制
Java的强引用,软引用,弱引用,虚引用及其使用场景 从 JDK1.2 版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引 ...
- java中的软引用,弱引用,虚引用
http://zh.wikipedia.org/wiki/%E5%BC%B1%E5%BC%95%E7%94%A8 有些语言包含多种强度的弱引用.例如Java,在java.lang.ref[1]包中定义 ...
随机推荐
- chattr 命令详解
chattr 作用: 改变文件属性,这项指令可改变存放在ext2文件系统上的文件或目录属性,这些属性共有一下8种模式 模式: a: 让文件或目录仅供附加用途 b: 不更新文件或目录的最后存取时间 ...
- QT中几个函数的使用方法
一.把字符串转换成整形demo1:QString str = "FF";bool ok;int hex = str.toInt(&ok, 16); // hex == 25 ...
- How to setup a DL4J project with eclipse
https://electronsfree.blogspot.com/2016/10/how-to-setup-dl4j-project-with-eclipse.html
- java多线程(二)-Runnable和Thread
Java在顺序性语言的基础上提供了多线程的支持.Java的线程机制是抢占式的.这表示调度机制会周期的中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片.(与抢占式多线程对应的是 协作式多线 ...
- java多线程(一)-概述
最近这段在看java多线程编程方面的东西.所以特写了几篇文章,来总结和回顾一下自己所学习到的相关知识.因为水平有限,文章中总结不全面甚至理解错误的地方,欢迎读者指点批评. 我们平时所接触到的程序,都是 ...
- 多行文字水平垂直居中在div
<BODY> <div class="box"> <h3>1.单行文字居中</h3> <!--设置行高来实现- ...
- zabbix-server端与zabbix-agent端部署与监控
环境: [root@redis ~]# uname -a Linux redis -.el6.x86_64 # SMP Tue Mar :: UTC x86_64 x86_64 x86_64 GNU/ ...
- Java学习笔记19---内部类之简介成员内部类、局部内部类及匿名内部类
内部类,顾名思义,即定义在某个类内部的类,称包含该内部类的类为外部类. 从定义的位置来说,分为成员内部类和局部内部类:从类的特征来说,分为匿名内部类和静态内部类. 今天先简要介绍一下前三种内部类的定义 ...
- [TLSR8266] 1、搭建tlsr8266编译框架在win服务器中
前言 泰凌微TLSR8266蓝牙芯片的开发环境在win桌面系统中搭建起来比较简单,在其论坛SDK版块->Telink IDE中可以找到安装包,直接安装即可生成基于Eclipse的开发环境,及相关 ...
- .net4.5中HttpClient使用注意点
.net4.5中的HttpClinet是个非常强大的类,但是在最近实际项目运用中发现了些很有意思的事情. 起初我是这样用的: using (var client = new HttpClient()) ...