java中引用的概念
强引用(StrongReference)
强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用:
|
1
2
|
Object object = new Object();String str = "hello"; |
只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。比如下面这段代码:
|
1
2
3
4
5
6
7
8
9
10
|
public class Main { public static void main(String[] args) { new Main().fun1(); } public void fun1() { Object object = new Object(); Object[] objArr = new Object[1000]; }} |
当运行至Object[] objArr = new Object[1000];这句时,如果内存不足,JVM会抛出OOM错误也不会回收object指向的对象。不过要注意的是,当fun1运行完之后,object和objArr都已经不存在了,所以它们指向的对象都会被JVM回收。
如果想中断强引用和某个对象之间的关联,可以显示地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。
软引用(SoftReference)
软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。下面是一个使用示例:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import java.lang.ref.WeakReference; public class Main { public static void main(String[] args) { SoftReference<String> sr = new SoftReference<String>(new String("hello")); System.out.println(sr.get()); System.gc(); //通知JVM的gc进行垃圾回收 System.out.println(sr.get()); }} |
弱引用(WeakReference)
弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。下面是使用示例:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import java.lang.ref.WeakReference; public class Main { public static void main(String[] args) { WeakReference<String> sr = new WeakReference<String>(new String("hello")); System.out.println(sr.get()); System.gc(); //通知JVM的gc进行垃圾回收 System.out.println(sr.get()); }} |
虚引用(PhantomReference)
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。
要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。虚引用与软引用和弱引用不同的是虚引用是在引用对象gc前加入队列,所以可以在这一段时间对引用对象进行清理操作。
进一步理解软引用和弱引用
对于强引用,我们平时在编写代码时经常会用到。而对于其他三种类型的引用,使用得最多的就是软引用和弱引用,这2种既有相似之处又有区别。它们都是用来描述非必需对象的,但是被软引用关联的对象只有在内存不足时才会被回收,而被弱引用关联的对象在JVM进行垃圾回收时总会被回收。针对上面的特性,软引用适合用来进行缓存,当内存不够时能让JVM回收内存,弱引用能用来在回调函数中防止内存泄露。因为回调函数往往是匿名内部类,隐式保存有对外部类的引用,所以如果回调函数是在另一个线程里面被回调,而这时如果需要回收外部类,那么就会内存泄露,因为匿名内部类保存有对外部类的强引用。
public static boolean isRun = true;
@SuppressWarnings("static-access")
public static void main(String[] args) throws Exception {
String abc = new String("abc");
System.out.println(abc.getClass() + "@" + abc.hashCode());
final ReferenceQueue<String> referenceQueue = new ReferenceQueue<String>();
new Thread() {
public void run() {
while (isRun) {
Object obj = referenceQueue.poll();
if (obj != null) {
try {
Field rereferent = Reference.class
.getDeclaredField("referent");
rereferent.setAccessible(true);
Object result = rereferent.get(obj);
System.out.println(obj);
System.out.println("gc will collect:"
+ result.getClass() + "@"
+ result.hashCode() + "\t"
+ (String) result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}.start();
PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc,
referenceQueue);
abc = null;
Thread.currentThread().sleep();
System.gc();
Thread.currentThread().sleep();
isRun = false;
}}
java中引用的概念的更多相关文章
- java中引用
java中引用分为,强,弱,虚,软 (1)强引用 使用最普遍的引用.如果一个对象具有强引用,它绝对不会被gc回收.如果内存空间不足了,gc宁愿抛出OutOfMemoryError,也不是会回收具有强引 ...
- java 中包的概念,常量,静态与继承
一.包的概念:创建,使用. 1.新建包: 最上面一行,之前不能再有其它代码了. package 包名; 注意:包名一般都有命名的规范.例如:com.itnba.maya.zy(从大到小). 2.使用包 ...
- 彻底搞明白PHP的中引用的概念
之前我们其实已经有过几篇文章讲过引用方面的问题,这次我们来全面的梳理一下引用在PHP到底是怎么回事,它和C中的指针有什么不同,在使用的时候要注意些什么. 什么是引用? 在 PHP 中引用意味着用不同的 ...
- Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义
一.Java中什么叫做引用类型变量?引用:就是按内存地址查询 比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...
- Java中引用类 strong reference .SoftReference 、 WeakReference 和 PhantomReference的区别
当在 Java 2 平台中首次引入 java.lang.ref 包,其中包含 SoftReference . WeakReference 和 PhantomReference 三个引用类,引用类的 ...
- Java中引用的浅复制和深复制
Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...
- Java中引用传递
//Java中的引用传递 class Ref1{ int temp = 10 ; String Str = "hello"; } public class HelloWorld { ...
- 关于java中指针的概念
今天寡人遇到一个问题,扫描非关系数据库中的图(由node和rel组成),将其转化成由寡人自定义的gnode和gedge组成的图. gnode类包含结点的id,label和包含此gnode的gedge的 ...
- Java中引用的详解
Java中没有指针,到处都是引用(除了基本类型).所以,当然,你肯定知道java的引用,并用了很久,但是是不是对此了解地比较全面?而这些引用有什么作用,且有什么不同呢?Java中有个java.lang ...
随机推荐
- jenkins 构建nodejs-pipeline流水风格的任务
Step3 上图代码如下 node("master"){ //warp([$class:'BuildUser']) {BUILD_USER = BUILD_USER} GIT_NA ...
- Overture小课堂之如何演绎钢琴滑音
在我们学习钢琴和学习使用Overture时,要学习如何弹奏和使用滑音.那么我们先来看看什么是滑音,如何使用钢琴演绎,在Overture里滑音又在哪里呢? 滑音,在音乐术语中通常指一种装饰音和演奏指法. ...
- Integer类toString(int i,int radix)方法
Integer类toString(int i,int radix)方法: 首先抛出java的api中的介绍: public static String toString(int i, int radi ...
- java代码块,静态代码块,静态变量,构造方法执行顺序
一个类中执行顺序: 静态变量静态代码块代码块构造方法 子类和父类执行顺序: 父类静态变量父类静态代码块子类静态变量子类静态代码块父类代码块父类构造方法子类代码块子类构造方法 直接看代码,一目了然. p ...
- UVA1479 Graph and Queries
思路 恶心人的题目 还是类似永无乡一题的Treap启发式合并思路 但是由于加边变成了删边 所以应该离线后倒序处理 数组要开够 代码 #include <cstdio> #include & ...
- django 开发笔记1
1.布置到云服务器 使用 python3 manage.py runserver提示错误,需要将settings.py 中 ALLOWED_HOSTS 字典中加入 localhost;0.0.0.0; ...
- vim中文乱码问题
问题如下: 修改 /etc/vimrc 文件 添加: ,ucs-bom,gb18030,gbk,gb2312,cp936 把/etc/vimrc复制到你自己的根目录下面:复制为.vimrc(前面有个点 ...
- 【GIT】【命令行】
1) 进入某没有做git的目录: git init ->username@DESKTOP-765V31O MINGW64 ~/PycharmProjects/user_data (master) ...
- 软件理论基础—— 第一章命题逻辑系统L
逻辑 语法 语义 推理系统 公理 推理规则 MP A,A->B =>B HS A->B,B->C => A->C 命题逻辑公式 ::= BNF backus ...
- Cordova入门系列(一)创建项目
Cordova是什么? 初学Cordova的人,虽然了解一点点,知道Cordova是用来将html, css, js变成app的,但并不知道到底是怎么用的,原理是什么.经常会有这样的困惑: 它是一个可 ...