Java和C++中的引用概念

Java中的引用
在Java中,所有的对象都是通过引用来访问的。这些引用类似于C++中的指针。当你创建一个对象时,Java会在堆内存中为该对象分配空间,并返回一个指向该对象的引用。你可以使用这个引用来访问和操作对象。
例如:
java
Person person = new Person(“John”);

在这个例子中,new Person(“John”)在堆内存中创建了一个新的Person对象,并返回了一个指向该对象的引用。这个引用被存储在person变量中,你可以使用person来访问和操作Person对象。
然而,Java中的引用与C++中的引用有一个重要的区别:在Java中,引用是可以重新指向其他对象的,而在C++中,引用一旦被初始化就不能改变,它将永远引用同一个对象。
此外,Java中的引用有四种类型:强引用、软引用、弱引用和虚引用,它们在垃圾回收方面有不同的行为。强引用是最常见的引用类型,如果一个对象有强引用,那么垃圾收集器就不会回收它。软引用、弱引用和虚引用允许你在内存紧张时回收对象,它们主要用于实现缓存和其他内存敏感的数据结构。
C++中的引用
在C++中,引用是一个已存在对象的别名。一旦引用被初始化为一个对象,它就不能被重新指向其他对象。换句话说,引用必须在创建时被初始化,并且一旦被初始化,就不能改变。
例如:
cpp
int x = 10;
int& ref = x;  // ref是x的引用,ref和x指向同一块内存

在这个例子中,ref是x的引用,ref和x指向同一块内存。你可以通过ref来访问和修改x的值。
C++中的引用主要用于函数参数传递和函数返回值。通过使用引用,你可以在函数中修改传递的参数的值,或者返回一个函数内部创建的对象。

强引用:这是使用最普遍的引用。如果一个对象具有强引用,那么垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
java
Person person = new Person(“John”); // person就是一个强引用

软引用:如果一个对象只具有软引用,那么在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收。如果这次回收还没有足够的内存,才会抛出内存溢出异常。在Java中,我们可以通过java.lang.ref.SoftReference类来实现软引用。
java
Person person = new Person(“John”);
SoftReference<Person> softReference = new SoftReference<>(person);

弱引用:如果一个对象只具有弱引用,那么在垃圾回收器线程扫描它所管辖的内存区域的过程中,只要发现弱引用关联的对象,不管当前内存空间足够与否,都会回收它的内存。在Java中,我们可以通过java.lang.ref.WeakReference类来实现弱引用。
java
Person person = new Person(“John”);
WeakReference<Person> weakReference = new WeakReference<>(person);

虚引用:也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。在Java中,我们可以通过java.lang.ref.PhantomReference类来实现虚引用。
java

Person person = new Person(“John”);
PhantomReference<Person> phantomReference = new PhantomReference<>(person, new ReferenceQueue<>());

 

垃圾回收和引用类型
Java的垃圾回收器主要负责回收堆内存中的对象。当一个对象没有任何引用指向它时,垃圾回收器就可以安全地回收这个对象的内存。然而,对于软引用、弱引用和虚引用指向的对象,垃圾回收器的行为就会有所不同。
软引用:垃圾回收器在内存不足时才会回收软引用指向的对象。这使得软引用非常适合用于实现内存敏感的缓存。如果内存充足,那么缓存中的对象就可以保留,如果内存不足,那么垃圾回收器就会回收这些对象,释放内存。
弱引用:垃圾回收器在扫描内存区域时,只要发现弱引用关联的对象,不管当前内存空间足够与否,都会回收它的内存。这使得弱引用适合用于实现一种特殊的数据结构——弱哈希映射(WeakHashMap),在这个映射中,当键不再被其他地方引用时,键值对就可以被垃圾回收。
虚引用:虚引用的存在不会阻止垃圾回收器回收它指向的对象。虚引用主要用于跟踪对象被垃圾回收的活动,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到引用队列中。
引用队列
Java提供了一个叫做引用队列(ReferenceQueue)的类,它可以和软引用、弱引用、虚引用一起使用,用于跟踪垃圾回收过程。当垃圾回收器准备回收一个对象,如果发现它还有软引用、弱引用或虚引用,并且这个引用关联了一个引用队列,那么垃圾回收器就会把这个引用加入到引用队列中。应用程序可以通过检查引用队列来了解哪些对象已经被垃圾回收。

强引用的使用场景
强引用是最常见的引用类型,我们在编程时经常使用。只要对象有强引用指向,垃圾回收器就不会回收它。因此,强引用是我们在编程时最常用的引用类型。
软引用的使用场景
软引用通常用于实现内存敏感的缓存。软引用可以让缓存的对象在内存充足时保留,而在内存不足时被回收。Java的SoftReference类就是用来实现软引用的。
例如,你可以使用软引用来实现一个图片缓存。当程序需要加载一张图片时,首先查看图片是否在缓存中。如果在,就直接使用缓存的图片;如果不在,就从磁盘或网络加载图片,并把图片添加到缓存中。由于缓存使用软引用,所以当内存不足时,垃圾回收器可以自动回收缓存中的图片。
弱引用的使用场景
弱引用可以用于实现一种特殊的数据结构——弱哈希映射(WeakHashMap)。在WeakHashMap中,当键不再被其他地方引用时,键值对就可以被垃圾回收。这对于需要自动释放值的场景非常有用。
例如,你可以使用WeakHashMap来实现一个监听器列表。当监听器对象不再被其他地方引用时,它就可以自动从监听器列表中移除。
虚引用的使用场景
虚引用主要用于跟踪对象被垃圾回收的活动。虚引用的存在不会阻止其引用的对象被垃圾回收,它在对象被垃圾回收器回收前会被加入到引用队列中。虚引用常常用于检测对象何时被自动清理。
例如,你可以使用虚引用来检测一个大型图像已经被完全加载,并且已经开始被使用。当图像对象被垃圾回收时,虚引用会被加入到引用队列,你的程序可以检查这个队列,知道何时图像对象已经被垃圾回收。

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年11月6日
下一篇 2023年11月6日

相关推荐