import org.apache.log4j.Logger;
import java.lang.management.ManagementFactory;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* 基于SoftReference做缓存,内存不足时自动回收。
* 线程安全性待测试。
* User: linannan
* Date: 12-4-9
* Time: 下午4:47
*/
public class SoftCache<K, V> {
protected static final Logger logger = Logger.getLogger(SoftCache.class);
private final ReferenceQueue queue;
private final Map<K, CacheEntry<K, V>> cache;
/**
* get取出后,避免被立即回收。
*/
private final LinkedList<V> hardLinksToAvoidGarbageCollection;
private int hardLinksNumber;
public SoftCache() {
queue = new ReferenceQueue();
cache = new ConcurrentHashMap<K, CacheEntry<K, V>>();
hardLinksToAvoidGarbageCollection = new LinkedList<V>();
hardLinksNumber = 256;
}
public void put(K key, V value) {
removeGarbageItems();
cache.put(key, new CacheEntry(key, value, queue));
}
public V get(K key) {
CacheEntry<K, V> entry = cache.get(key);
if (entry == null) {
return null;
} else {
V value = entry.get();
if (value == null) {
cache.remove(key);
} else {
/**
* 增加一个强引用,免得被回收了
*/
hardLinksToAvoidGarbageCollection.addFirst(value);
if (hardLinksToAvoidGarbageCollection.size() > hardLinksNumber) {
hardLinksToAvoidGarbageCollection.removeLast();
}
return value;
}
}
return null;
}
/**
* 清空缓存
*/
public void clear() {
hardLinksToAvoidGarbageCollection.clear();
removeGarbageItems();
cache.clear();
}
/**
* 删除已经被回收掉的
*/
public void removeGarbageItems() {
Reference r = null;
while ((r = queue.poll()) != null) {
CacheEntry entry = (CacheEntry) r;
logger.debug("内存不足,remove->" + entry.key);
cache.remove(entry.key);
}
}
public int size() {
removeGarbageItems();
return cache.size();
}
public Set<K> keySet(){
return cache.keySet();
}
private static class CacheEntry<K, V> extends SoftReference<V> {
K key;
public CacheEntry(K key, V value, ReferenceQueue queue) {
super(value, queue);
this.key = key;
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("test");
SoftCache cache = new SoftCache();
for (int i = 0; i < 2000000; i++) {
try {
cache.put("" + i, "" + i);
} catch (OutOfMemoryError error) {
System.out.println(error.getMessage());
System.gc();
}
}
System.out.println(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed() / 1000 / 1000);
System.out.println(cache.size());
System.gc();
System.out.println(cache.size());
Thread.sleep(2000);
System.gc();
Thread.sleep(2000);
System.out.println(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed() / 1000 / 1000);
System.gc();
System.out.println(cache.size());
}
}
分享到:
相关推荐
本压缩包"ArcGIS_Server_Search.rar"包含了与JAVA缓冲区、JAVA地图以及地图发布相关的资料,这将帮助我们理解如何利用Java技术在ArcGIS Server上实现地图服务的功能,如地图查询、地图搜索以及缓冲区分析。...
Java 缓冲流是Java I/O流中的一个重要概念,它主要设计用于提高程序在处理输入输出操作时的性能。在创建缓冲流对象时,系统会自动创建一个内部的默认大小的缓冲区数组,数据的读写操作都是在这个缓冲区中进行,而...
在这个特定的案例"SuperMap Objects Java线对象缓冲区分析"中,我们将深入探讨如何在Java环境下利用SuperMap Objects进行线对象的缓冲区分析。 首先,我们要理解什么是缓冲区分析。缓冲区分析是GIS中的一个基本操作...
摘要:Java源码,图形操作,缓冲区 Java创建缓冲区图像示例,演示如何来创建缓冲区图像,并且将图像显示出来。缓冲区图像是指直接在计算机内存中内创建的图像,因此可以对其进行像素级的处理,完成及其复杂的图像变换...
在计算机科学领域,Buffer(缓冲区)是一种重要的概念,它在数据处理中起着至关重要的作用。Buffer的应用广泛,特别是在网络编程,尤其是Socket编程中,它扮演着数据传输的桥梁角色。本文将深入探讨Buffer的基本原理...
虚拟内存和缓冲流,直接粘贴到eclipse或者cmd运行即可
### 利用缓冲区提高Java应用程序的IO性能 #### 摘要与背景介绍 Java作为一门具有跨平台特性的编程语言,在多个领域都获得了广泛的应用。随着Java应用的不断扩展,其性能问题逐渐成为人们关注的重点,尤其是输入...
本篇文章将深入探讨如何使用Java生成线缓冲区,并结合Eclipse IDE进行开发。 首先,我们需要了解Java中的GIS库,例如JTS(Java Topology Suite)和GeoTools。JTS是一个强大的开源库,提供了一系列的几何操作,包括...
【Java 双缓冲技术】 Java 作为一种强大的开发语言,在游戏编程和多媒体动画处理领域具有显著的优势。然而,当涉及到动态图形显示时,一个常见的问题是屏幕闪烁。本文将深入探讨这个问题,以及如何通过双缓冲技术来...
### Java双缓冲消除闪烁 #### 一、问题的引入与分析 在进行Java游戏开发或者多媒体动画处理时,经常会遇到屏幕闪烁的问题。这种现象不仅影响视觉体验,还可能降低应用程序的专业性和用户满意度。屏幕闪烁主要发生...
Java双缓冲技术是一种提高图形界面性能的策略,尤其在绘制复杂的UI组件时,能有效避免闪烁现象,提供平滑的视觉体验。双缓冲的核心思想是将屏幕上的绘图操作先在一个临时缓冲区进行,待全部操作完成后再一次性将缓冲...
Java双缓冲技术是一种图形渲染优化策略,主要用于提高GUI(图形用户界面)的性能和减少屏幕闪烁,提升用户体验。在Java中,它主要应用于Swing和JavaFX等图形库。本教程将深入探讨Java双缓冲技术的原理,并通过实例...
在Java编程语言中,"画图(双缓冲)"是一个重要的技术概念,它涉及到图形用户界面(GUI)的开发和优化。双缓冲是一种图形渲染技术,用于提高在屏幕上绘制复杂图形时的性能和质量,避免闪烁和不连续的视觉效果。在本...
**安全编程之缓冲区溢出** 在IT领域,安全编程是一项至关重要的技能,尤其是在系统和应用程序设计中。缓冲区溢出是其中最常见的安全漏洞之一,它可能导致数据丢失、程序崩溃,甚至恶意代码执行,对系统安全构成严重...
Java字节缓冲流原理与用法详解 Java字节缓冲流是Java IO系统中的一种重要组成部分,用于提高IO操作的性能。下面将详细介绍Java字节缓冲流的原理和用法。 一、Java字节缓冲流原理 Java字节缓冲流是一种基于缓冲区...
Java双缓冲技术 Java双缓冲技术是计算机动画处理中的传统技术,广泛应用于Java游戏编程和多媒体动画处理中。该技术的主要作用是消除屏幕闪烁,以提高动画的流畅度和用户体验。 Java双缓冲技术的原理是将屏幕分为...
Java 缓冲流是Java I/O流中的一个重要概念,它极大地提高了程序处理数据的效率。在Java中,I/O操作通常涉及到大量的磁盘或网络读写,这些操作速度相对较慢,而缓冲流通过在内存中建立一个临时的数据缓冲区,减少了与...
1.什么是缓冲流,有什么作用? 这里需要说明一点小知识,在对硬盘进行读写操作时,一个完整的文件的读写速率要远远高于同样大小的散文件的读写速率。这是因为散文件需要不断地访问、关闭硬盘,极大地浪费了时间,...
Java 字符流缓冲区详解 Java 字符流缓冲区是 Java 中用于提高 IO 操作效率的一种机制,它通过在内存中缓存一部分数据,然后批量写入或读取,以提高流的读写效率。在 Java 中,BufferedReader 和 BufferedWriter 是...
为了解决这个问题,Java提供了“双缓冲”技术。本文将深入探讨Java中的双缓冲绘图,以及如何在AWT窗体上实现这一技术。 双缓冲是一种优化图形绘制的技术,它通过在内存中创建一个临时的“缓冲区”,在这个缓冲区中...