Java面试题19 牛客下面有关java的引用类型,说法正确的有?

Java面试题19下面有关java的引用类型,说法正确的有?

A:对于一个对象来说,只要有强引用的存在,它就会一直存在于内存中
B:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
C:如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存
D:一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的空间

蒙蔽树下蒙蔽果,蒙蔽树上你和我

引用与对象

每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过“引用”。
在 Java 中一切都被视为了对象,但是我们操作的标识符实际上是对象的一个引用(reference)。

//创建一个引用,引用可以独立存在,并不一定需要与一个对象关联
String s;

通过将这个叫“引用”的标识符指向某个对象,之后便可以通过这个引用来实现操作对象了。

String str = new String("abc");
System.out.println(str.toString());

在 JDK1.2 之前,Java中的定义很传统:如果 reference 类型的数据中存储的数值代表的是另外一块内存的起始地址,就称为这块内存代表着一个引用。
Java 中的垃圾回收机制在判断是否回收某个对象的时候,都需要依据“引用”这个概念。
在不同垃圾回收算法中,对引用的判断方式有所不同:

  • 引用计数法:为每个对象添加一个引用计数器,每当有一个引用指向它时,计数器就加1,当引用失效时,计数器就减1,当计数器为0时,则认为该对象可以被回收(目前在Java中已经弃用这种方式了)。
  • 可达性分析算法:从一个被称为 GC Roots 的对象开始向下搜索,如果一个对象到GC Roots没有任何引用链相连时,则说明此对象不可用。

JDK1.2 之前,一个对象只有“已被引用”和"未被引用"两种状态,这将无法描述某些特殊情况下的对象,比如,当内存充足时需要保留,而内存紧张时才需要被抛弃的一类对象。

四种引用类型

所以在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱。

一,强引用

Java中默认声明的就是强引用,比如:

Object obj = new Object(); //只要obj还指向Object对象,Object对象就不会被回收
obj = null;  //手动置null

只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了

二,软引用

软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。
在 JDK1.2 之后,用java.lang.ref.SoftReference类来表示软引用。

下面以一个例子来进一步说明强引用和软引用的区别:
在运行下面的Java代码之前,需要先配置参数 -Xms2M -Xmx3M,将 JVM 的初始内存设为2M,最大可用内存为 3M。

首先先来测试一下强引用,在限制了 JVM 内存的前提下,下面的代码运行正常

public class TestOOM {public static void main(String[] args) {testStrongReference();}private static void testStrongReference() {// 当 new byte为 1M 时,程序运行正常byte[] buff = new byte[1024 * 1024 * 1];}
}

但是如果我们将

byte[] buff = new byte[1024 * 1024 * 1];

替换为创建一个大小为 2M 的字节数组

byte[] buff = new byte[1024 * 1024 * 2];

则内存不够使用,程序直接报错,强引用并不会被回收

接着来看一下软引用会有什么不一样,在下面的示例中连续创建了 10 个大小为 1M 的字节数组,并赋值给了软引用,然后循环遍历将这些对象打印出来。

public class TestOOM {private static List<Object> list = new ArrayList<>();public static void main(String[] args) {testSoftReference();}private static void testSoftReference() {for (int i = 0; i < 10; i++) {byte[] buff = new byte[1024 * 1024];SoftReference<byte[]> sr = new SoftReference<>(buff);list.add(sr);}System.gc(); //主动通知垃圾回收for(int i=0; i < list.size(); i++){Object obj = ((SoftReference) list.get(i)).get();System.out.println(obj);}}}

打印结果:

我们发现无论循环创建多少个软引用对象,打印结果总是只有最后一个对象被保留,其他的obj全都被置空回收了。
这里就说明了在内存不足的情况下,软引用将会被自动回收。
值得注意的一点 , 即使有 byte[] buff 引用指向对象, 且 buff 是一个strong reference, 但是 SoftReference sr 指向的对象仍然被回收了,这是因为Java的编译器发现了在之后的代码中, buff 已经没有被使用了, 所以自动进行了优化。
如果我们将上面示例稍微修改一下:

    private static void testSoftReference() {byte[] buff = null;for (int i = 0; i < 10; i++) {buff = new byte[1024 * 1024];SoftReference<byte[]> sr = new SoftReference<>(buff);list.add(sr);}System.gc(); //主动通知垃圾回收for(int i=0; i < list.size(); i++){Object obj = ((SoftReference) list.get(i)).get();System.out.println(obj);}System.out.println("buff: " + buff.toString());}

则 buff 会因为强引用的存在,而无法被垃圾回收,从而抛出OOM的错误。

如果一个对象惟一剩下的引用是软引用,那么该对象是软可及的(softly reachable)。垃圾收集器并不像其收集弱可及的对象一样尽量地收集软可及的对象,相反,它只在真正 “需要” 内存时才收集软可及的对象。

三,弱引用

弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。
我们以与软引用同样的方式来测试一下弱引用:

    private static void testWeakReference() {for (int i = 0; i < 10; i++) {byte[] buff = new byte[1024 * 1024];WeakReference<byte[]> sr = new WeakReference<>(buff);list.add(sr);}System.gc(); //主动通知垃圾回收for(int i=0; i < list.size(); i++){Object obj = ((WeakReference) list.get(i)).get();System.out.println(obj);}}

打印结果:

可以发现所有被弱引用关联的对象都被垃圾回收了。

四,虚引用

虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。

public class PhantomReference<T> extends Reference<T> {/*** Returns this reference object's referent.  Because the referent of a* phantom reference is always inaccessible, this method always returns* <code>null</code>.** @return  <code>null</code>*/public T get() {return null;}public PhantomReference(T referent, ReferenceQueue<? super T> q) {super(referent, q);}
}

那么传入它的构造方法中的 ReferenceQueue 又是如何使用的呢?

五,引用队列(ReferenceQueue)

引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。

与软引用、弱引用不同,虚引用必须和引用队列一起使用。

我是歌谣,有不合理之处欢迎指出。喜欢敲代码,偶尔耍耍题。

正确答案: A B C D  

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期更新计算机领域知识)

阅读目录(置顶)(长期科技领域知识)

歌谣带你看java面试题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MapReduce运行机制

相关链接 MapReduce中Shuffle机制详解——Map端Shuffle链接 MapReduce中Shuffle机制详解——Reduce端Shuffle链接MapReduce将作业job的整个运行过程分为两个阶段&#xff1a;Map阶段和Reduce阶段。按照时间顺序包括&#xff1a;输入分片&#xff08;input split&#xff09;、m…

WebService Software Factory 设计草图

以下是根据WSSF设计理念&#xff0c;按现公司的业务需求设计的接口项目拟稿&#xff0c;实现细分。仅供参考。&#xff08;WSSF---ASMX版&#xff09; 建议用1680*1050分辩浏览 转载于:https://www.cnblogs.com/RuiLei/archive/2008/10/05/1304160.html

Java面试题 20在面向对象编程里,经常使用is-a来说明对象之间的继承关系

Java面试题 20在面向对象编程里&#xff0c;经常使用is-a来说明对象之间的继承关系&#xff0c;下列对象中不具备继承关系的是&#xff1f;&#xff08;&#xff09; A:手机与小米手机 B&#xff1a;企业家与雷军 C:编程语言与Java D&#xff1a;中国与北京 类之间存在以下…

MapReduce计数器

原文链接&#xff1a;http://itfish.net/article/61067.html 1、MapReduce计数器是什么&#xff1f;计数器是用来记录job的执行进度和状态的。它的作用可以理解为日志。我们可以在程序的某个位置插入计数器&#xff0c;记录数据或者进度的变化情况。 2、MapReduce计数器能做什么…

编写“线围棋”程序-2-可开局

棋盘有了&#xff0c;怎么支持在上面落子呢&#xff1f; 只要解决下面3个问题就可以了&#xff1a; 1.响应鼠标点击事件&#xff0c;获得“下棋子”的动作源。 2.修改和记录棋局状态。 3.在棋盘上显示棋局的状态。 为此&#xff0c;直接增加一个“棋局类“&#xff0c;也就是对…

Java面试题 21 下列说法正确的有()

下列说法正确的有&#xff08;&#xff09; A 能被java.exe成功运行的java class文件必须有main()方法 B J2SDK就是Java API C:Appletviewer.exe可利用jar选项运行.jar文件 D能被Appletviewer成功运行的java class文件必须有main()方法 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下…

[翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb

SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb 您是否曾经写过代码来处理数据库中的所有表&#xff1f;处理一个 SQL Server实例中的所有数据库的代码又该如何写&#xff1f;然则&#xff0c;您是否知道有多种方法可以解决这问题&#xff1f;您可以创建…

Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持

Java面试题 22 牛客 Java是一门支持反射的语言,基于反射为Java提供了丰富的动态性支持&#xff0c;下面关于Java反射的描述&#xff0c;哪些是错误的&#xff1a;( ) A Java反射主要涉及的类如Class, Method, Filed,等&#xff0c;他们都在java.lang.reflet包下 B 通…

java面试题24 关于Java中的数组,

java面试题24 关于Java中的数组&#xff0c;下面的一些描述&#xff0c;哪些描述是准确的&#xff1a;&#xff08; &#xff09; A 数组是一个对象&#xff0c;不同类型的数组具有不同的类 B 数组长度是可以动态调整的 C 数组是一个连续的存储结构 D:一个固定长度的…

[开发技巧3]不显示报表直接打印

水晶报表9.2VB6 使用Application可以进行打印 在将数据赋给报表模板后&#xff0c;调用PrintOut方法 赋给报表数据objCRReport.Database.SetDataSource rst 此句打印&#xff0c;会出现打印提示框objCRReport.PrintOut 不提示&#xff0c;直接打印到默认打印机CallobjCRReport.…

SQL开发中容易忽视的一些小地方( 三)

目的&#xff1a;这篇文章我想说说我在工作中关于in和union all 的用法. 索引定义 &#xff1a; 微软的SQL SERVER提供了两种索引&#xff1a;聚集索引(clustered index&#xff0c;也称聚类索引、簇集索引)和非聚集索引(nonclustered index&#xff0c;也称非聚类索引、非簇集…

java面试题26 java语言的下面几种数组复制方法中,哪个效率最高?

java面试题26 java语言的下面几种数组复制方法中&#xff0c;哪个效率最高&#xff1f; A for 循环逐一复制 B System.arraycopy C Array.copyOf D 使用clone方法 效率&#xff1a;System.arraycopy > clone > Arrays.copyOf > for循环 1、System.arraycopy的用法…

pycharm使用笔记2-远程连接(转)

原文地址:https://blog.csdn.net/jinxiaonian11/article/details/70208920 随着科技的发展&#xff0c;远程办公已经是一种趋势&#xff0c;远程开发能力对于每一个程序员来说都是必不可少的。有时候就算在公司&#xff0c;在进行开发的时候有许多的数据都是储存在服务器上的&a…

java面试题27 java中下面哪些是Object类的方法()

java面试题27 java中下面哪些是Object类的方法&#xff08;&#xff09; A notify() B notifyAll() C sleep() D wait() 蒙蔽树上蒙蔽果&#xff0c;蒙蔽树下你和我。遇到这种题&#xff0c;我默默的打开了编译工具 Object类中方法&#xff1a; protected Object clone()…

shiro学习(1):shiro简介

Apache Shiro是Java的一个安全框架。对比另一个安全框架Spring Sercurity&#xff0c;它更简单和灵活。 Shiro可以帮助我们完成&#xff1a;认证、授权、加密、会话管理、Web集成、缓存等。 Apache Shiro特性 Authentication&#xff1a;身份认证/登录&#xff0c;验证用户是…

微软启动了自爆程序,让我们一起帮它倒计时

……“公元2008年10月20日&#xff0c;注定成为人类信息技术史上不平凡的一天&#xff0c;因为在这一天&#xff0c;曾经创造了无数辉煌的计算机软件帝国微软公司&#xff0c;启动了自爆程序&#xff0c;剩下的&#xff0c;就是倒计时了……” ——《地球人类信息技术编年史》 …

python字典遍历的几种方法(转)

源地址&#xff1a;https://www.cnblogs.com/stuqx/p/7291948.html&#xff08;1&#xff09;遍历key值>>> a {a: 1, b: 2, c: 3} >>> for key in a:print(key:a[key])a:1 b:2 c:3 >>> for key in a.keys():print(key:a[key])a:1 b:2 c:3在使用上&a…

shiro学习(2):第一个shiro程序

工具idea 首先创建maven项目 配置文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

shiro学习(3):用户权限

工具idea 首先创建maven项目 配置文件 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

WPF学习笔记(三)

1.1 事件概括 第一节中我们给窗体添加了一个按钮&#xff0c;不过好像Button点个几下也只有些发光样式的变化&#xff0c;什么你还把系统皮肤去掉了&#xff1f;算了承认下确实够寒碜&#xff0c;那让我们再动动手。 1.1.1 路由事件简述 public HelloWorld() { Button button …