java中的四种引用分别是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
每一种语言都有着自己操作内存元素的方式,C语言通过指针,而java就是通过引用。作为一门面向对象的语言,在java中世事万物皆对象。但是我们操作的标识符实际上是对象的一个引用(reference)。今天我们来分析一下java中的四种引用。
一、引用的历史
在Java中,我们的垃圾回收机制回收垃圾对象的时候就会依据对象的引用。比如说通过不同的垃圾回收算法,这里有两种:引用计数法和可达性分析法
1、引用计数法:为每个对象添加一个引用计数器,每当有一个引用指向它时,计数器就加1,当引用失效时,计数器就减1,当计数器为0时,则认为该对象可以被回收。
2、可达性分析算法:从一个被称为 GC Roots 的对象开始向下搜索,如果一个对象到GC Roots没有任何引用链相连时,则说明此对象不可用。
目前的垃圾回收基本上采用第二种方式,第一种方式基本上已经被舍弃了。
在jdk1.2之前,java对引用的概念只有“已被引用”和"未被引用"两种状态。后来所以在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用、软引用、弱引用、虚引用4 种,也就是我们今天所讲的主题。这 4 种引用的强度依次减弱。
二、四种引用
1、强引用
如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。比如String str = "hello"这时候str就是一个强引用。当然我们也可以使用str=null取消一个强引用。下面我们使用代码来测试一下强引用:
前提是我们先要设置一些jvm参数, -Xms2M -Xmx3M表示初始内存是2M,最大内存是3M。设置的步骤如下:
步骤:
1、选中已经写好的项目
2、Run->Debug configurations->Java Application 双击
3、Arguments->VM arguments
4、在VM arguments 里面就可以对虚拟机的内存参数进行设置
5、设置完成后,Apply->Debug
1public class Test {
2 public static void main(String[] args) {
3 testStrongReference();
4 }
5 private static void testStrongReference() {
6 //1M的时候是正常的,但是我们调到3M这时候就会出现OutOfMemoryError
7 byte[] buff = new byte[1024 * 1024 * 3];
8 }
9}
2、软引用
如果一个对象具有软引用,它就不会被垃圾回收器回收。只有在内存空间不足时,软引用才会被垃圾回收器回收。这种引用常常被用来实现缓存技术。因为缓存区里面的东西,之后在内存不足的时候才会被清空。下面我们再进行测试一下:前提是设置虚拟机参数 -Xms2M -Xmx3M。
1private static void testSoftReference() {
2 //创建10个大小为1M的字节,赋值给软引用
3 for (int i = 0; i < 10; i++) {
4 byte[] buff = new byte[1024 * 1024];
5 SoftReference<byte[]> sr = new SoftReference<>(buff);
6 list.add(sr);
7 }
8 //主动通知JVM,建议回收
9 System.gc();
10 //循环遍历出来
11 for(int i=0; i < list.size(); i++){
12 Object obj = ((SoftReference) list.get(i)).get();
13 System.out.println(obj.toString());
14 }
15}
我们可以测试一下,会发现只有最后一个软引用对象打印了出来,其他的全部为null。这是为什么呢?这是因为我们设置的参数是最大3M,内存不足的时候,会主动回收这些对象垃圾。
3、弱引用
如果一个对象具有弱引用,在垃圾回收时候,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。我们把上面的对象如果改成弱引用的话,你会发现所有的全部为空,这就是因为创建了10个1M的对象,超出了3M,无论内存是否足够,都会被回收。
4、虚引用
如果一个对象具有弱引用,就相当于没有引用,在任何时候都有可能被回收。虚引用是使用PhantomReference创建的引用,虚引用也称为幽灵引用或者幻影引用,是所有引用类型中最弱的一个。一个对象是否有虚引用的存在,完全不会对其生命周期构成影响,也无法通过虚引用获得一个对象实例。
使用虚引用的目的就是为了得知对象被GC的时机,所以可以利用虚引用来进行销毁前的一些操作,比如说资源释放等。这个虚引用对于对象而言完全是无感知的,有没有完全一样,但是对于虚引用的使用者而言,就像是待观察的对象的把脉线,可以通过它来观察对象是否已经被回收,从而进行相应的处理。
看完上述内容,你们掌握java中的四种引用分别是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。