强引用的概念
在讲解强引用之前,需要先介绍一下垃圾回收的概念。在程序运行过程中,堆内存中的一些对象有可能不再被使用,但是它们所占用的内存仍然没有被释放,这时候就需要一个机制来清理这些不再被使用的对象,这个就是垃圾回收机制。在Java中,垃圾回收是由JVM实现的。
强引用是Java中最常见的一种引用类型,也是默认的引用类型。强引用的特点是:只要强引用存在,垃圾回收器就不会回收该对象。JVM把运行时数据区分为栈和堆,栈用于存储局部变量和函数调用的上下文,堆用于存储对象,强引用是存在于栈中的引用,如果栈中有一个强引用指向堆中的某个对象,那么这个对象就算是被强引用指向的,也就是它正在被引用。
强引用的使用攻略
在实际开发中,强引用也是最常见的引用类型。下面我们就来详细讲解一下强引用的使用攻略:
1. 使用简单
强引用通常是自然而然地使用的。比如:
Object obj = new Object();
上面的代码中,obj就是一个强引用,指向了一个新创建的Object对象。这个Object对象只要引用存在,就不会被垃圾回收器回收。当obj不再被使用时,只需要将其赋值为null,那么这个对象就可以被垃圾回收器回收了。
2. 防止内存泄漏
在一些场景下,可能会出现内存泄漏的问题。内存泄漏是指在程序运行过程中,没有使用的对象没有被释放,从而导致系统内存占用过多,影响系统性能。强引用也可以通过一些技巧来防止内存泄漏。
比如,当我们使用一些第三方库的时候,可能存在这样的情况:我们传递一个对象给第三方库,但是我们在使用完这个对象之后没有进行垃圾回收,从而导致占用了过多的内存。这时候我们可以使用弱引用或软引用来间接引用这个对象,这样就可以避免内存泄漏的问题。
还有一种情况是对象被存储在集合类中,但是忘记将对象从集合中移除。这里我们可以使用WeakHashMap(弱引用),当对象没有强引用指向时,会被自动从WeakHashMap中移除,从而避免内存泄漏。
示例说明
示例一:使用强引用
public static void main(String[] args) {
Object obj = new Object();
System.out.println(obj.toString());
obj = null;
System.out.println("执行垃圾回收...");
System.gc();
}
上面的代码创建了一个Object对象,将其赋值给一个强引用obj。在执行完obj = null之后,我们调用System.gc()手动触发垃圾回收操作,从而可以看到obj指向的对象被垃圾回收机制所回收。
示例二:防止内存泄漏
public class Test {
public static void main(String[] args) {
Map<String, Object> map = new WeakHashMap<>();
map.put("obj", new Object());
System.out.println(map.get("obj").toString());
System.gc();
System.out.println("执行垃圾回收...");
System.out.println(map.get("obj"));
}
}
上面的代码创建了一个WeakHashMap对象,并将一个Object对象放入其中,通过弱引用间接引用这个对象。在执行完System.gc()之后,我们可以看到map.get(“obj”)返回null,说明对象已经被回收掉了。从而避免了内存泄漏的问题。