本文将深入地介绍关于引用对象(Reference Objects)的知识。基本上说,引用对象提供了一种对象间接引用所需内存的方式,这些引用对象保存在一个引用对象中(类ReferenceQuene),它监视这些引用对象使得其可以访问。基于这种类型的引用对象,垃圾回收器能够释放内存,而一般的对象引用则可能无法释放。
在Java中,有四种类型的对象引用。常用的是直接引用,如:
Object obj = new Object()
您可以将直接引用当作一种无需额外的代码去创建或访问对象的一种强引用。接下来的三种类型的引用是java.lang.ref包中的Reference类的子类。软引用(Soft reference)由SoftReference类提供,弱引用(weak reference)由WeakReference类提供,幻像引用(PhantomReference)由PhantomReference提供。
软引用的工作方式很像数据缓存。当系统内存太低的时候,GC可以任意地释放软引用所引用的对象。换句话说,如果一个对象没有强引用,那么这个对象就是一个候选释放对象。在抛出OutOfMemoryException异常之前,GC将要求释放任何软引用。
弱引用比软引用弱。如果对象的引用只有弱引用,则GC将可能在任何时候回收内存,而不需要等到内存不足的时候。典型的动作是GC在下一个回收周期中对象的内存被回收。
幻像引用与清理任务有关。他们提供了一种在GC执行终止程序和释放对象之前即时通知机制。将其理解为在一个对象之前进行的清理任务。
下面是WeakHashMap的一个简单示例。WeakTest程序创建一个WeakHashMap的对象,里面含有一个元素。接着创建了第二个线程等待map清空,要求GC每0.5秒执行一次。主线程等待第二线程完成。
import java.util.*;
public class WeakTest {
private static Map<String, String> map;
public static void main (String args[]) {
map = new WeakHashMap<String, String>();
map.put(new String("Scott"), "McNealey");
Runnable runner = new Runnable() {
public void run() {
while (map.containsKey("Scott")) {
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
System.out.println("Checking for empty");
System.gc();
}
}
};
Thread t = new Thread(runner);
t.start();
System.out.println("Main joining");
try {
t.join();
} catch (InterruptedException ignored) {
}
}
}
因为在map仅有一个键没有强引用,在map中的项会在最近的一个垃圾回收周期内回收。
运行该程序将输出:
Main joining
Checking for empty
有两个重要的地方需要指出。第一,正常情况下System.gc()不需要明确地调用。但是因为WeakTest是一个非常轻量级的程序,它不需要使用更多的内存,因此明确地调用垃圾回收机制是必要的。第二,注意到new String("Scott")这一行,你可能会问为什么不直接使用"Scott"而需要new呢?答案是如果你不使用new,那么作为map的键的该字符串在系统的字符串常量池中有一个引用。这将不会移除,所以弱引用也不会释放。为了解决这个问题,需要使用new创建一个特定的引用去引用字符串常量池中的引用。字符串的内容不会重复。它们保留在常量池中。这只是简单地创建了一个单独的指针指向该字符串。
分享到:
相关推荐
书中还提到可以用WeakHashMap来作为缓存的容器可以有效解决这一问题。之前也确实遇到过类似问题,但是没有接触过“弱引用”相关的问题,于是查阅了一些资料。 《Java 理论与实践: 用弱引用堵住内存泄漏》一文也...
CPU过高通常与过度的计算、无尽循环、死锁、线程竞争状态等问题相关。在Java编程中,WeakHashMap是一种特殊的哈希表,它的键(Key)是弱引用,当键被垃圾回收器清除后,即使有值(Value)存在,该条目也会自动从哈希...
本篇将分享关于开发过程中的一些关键知识点,特别是有关数据结构和集合框架的部分。 首先,让我们讨论`Hashtable`和`HashMap`的区别。`Hashtable`是`Dictionary`的子类,它是一个线程安全的容器,其方法默认是同步...
这使得弱引用常用于实现内存敏感的数据结构,如`WeakHashMap`。 - 示例:`WeakReference<String> weakRef = new WeakReference(new String("Hello"));` 4. **虚引用(Phantom Reference)** - 虚引用也称为幽灵...
基础 IO 类和相关方法InputStream OutputStream Reader 类Writer 类 InputStream 及其子类 OutputStream 及其子类Reader 及其子类Writer 及其子类 注解 关于 null 的几种处理方式大小写敏感 null 是任何引用类型的...
【Java内存泄漏问题相关总结】 在Java编程中,内存泄漏是一个严重的问题,它指的是程序中已分配的内存没有被正确地释放,导致这部分内存无法被垃圾收集器(GC)回收,长时间积累会消耗大量系统资源,影响应用性能。...
除了上述实现类,还有WeakHashMap、IdentityHashMap等特殊用途的Map实现,它们分别处理弱引用和比较对象引用相等的情况。 在实际开发中,选择合适的Map实现类取决于具体需求,如是否需要有序、是否考虑线程安全、...
以下是对Java集合框架及相关知识点的详细解释: 1. **集合接口**:在Java中,集合分为List、Set和Queue三类,它们都继承自Collection接口。ArrayList、LinkedList、HashSet、TreeSet、LinkedList和PriorityQueue是...
对于 Tomcat 而言,内存泄漏常常与类加载器(ClassLoader)有关,特别是 WebappClassLoader。WebappClassLoader 是 Tomcat 为每个部署的应用程序实例创建的,负责加载该应用的类和资源。在热部署场景下,当应用被...
- **数据库索引**:键作为查询条件,能够快速定位到相关的记录。 - **图算法**:表示顶点与顶点之间的邻接关系,或者存储图的属性信息。 - **编译器和解释器**:在编译器或解释器中用于实现符号表,存储变量名与...
在Java编程语言中,弱引用是一种特殊的引用类型,它允许...通过WeakReference类以及相关数据结构如WeakHashMap,Java为开发者提供了实现这一目标的工具。在实际应用中,合理使用弱引用能够提升程序的性能和稳定性。
这里有几个关键的区别,它们有效地定义了WeakObjectPool: WeakHashMap具有弱键而不是值,例如WeakObjectPool。 它是一个池而不是一个地图,否则也称为多地图。 WeakObjectPool允许您在对象(装饰器)的生命周期...
3. **集合框架**:Java集合框架包括List(ArrayList、LinkedList)、Set(HashSet、TreeSet)、Map(HashMap、TreeMap、WeakHashMap)。理解它们的特性和使用场景,以及迭代器的使用,是面试中的重点。 4. **多线程...
- 缓存应用图标,避免每次绘制时都重新加载,可以使用内存缓存(例如WeakHashMap)或者LruCache。 在`MainView2.0`这个文件中,很可能是实现了上述功能的一个主要视图类或模块。这个文件可能包含了自定义Adapter的...
如果涉及到大量数据的缓存,还可能会用到内存缓存机制,如Java的WeakHashMap或第三方库如Google的Guava Cache。 在实际部署时,这个应用可能需要一个服务器环境来运行,比如使用Tomcat或Jetty这样的Java应用服务器...
LinkedHashMap保持插入顺序,WeakHashMap则允许弱引用键,当键不再被引用时,键值对会自动从Map中移除。TreeMap按照键的自然顺序或自定义比较器进行排序。 IdentityHashMap与HashMap类似,但其比较键时使用的是...
2. Map接口:掌握HashMap、TreeMap、WeakHashMap等Map实现类的特性。 3. 集合操作:熟悉迭代器、遍历、添加、删除、查找等操作。 4. 泛型:理解泛型的概念,以及泛型通配符和边界。 五、多线程 1. 线程创建:使用...
Android的WeakHashMap或者LruCache可以用来做内存缓存,它们能根据系统内存动态调整缓存大小,防止内存泄漏。 3. **磁盘缓存**:当内存不足以存储所有图片时,可以将图片保存到设备的磁盘上。这通常是在文件系统的...
本文将深入介绍这个框架,特别是针对Collection、List、Set以及相关API。 1. **Collection接口**: Collection是最基本的集合接口,它定义了所有集合的基本行为。Collection接口提供了添加、删除、检查元素等方法...