我正在用Java管理一个存储用户数据的项目.用户可以在线或离线.当用户在线时,他们的数据被加载到数据对象中以便于访问,并在他们注销时卸载.
但是,对于离线用户,为了防止数据同时访问来自同时操作数据的多个命令的数据,我将weakhashmap存储为加载的用户数据对象的缓存.如果需要访问脱机数据对象以进行修改,系统将在从文件加载之前先检查缓存.
我能想到如何存储它们的唯一方法是使用字符串键,它代表用户的用户名.但是由于java的工作原理,由于VM的字符串缓存系统,这似乎并不总是有效.
最初我想过使用字符串包装器,但是再次因为hashmaps如何工作(通过使用hashcode),创建一个新的字符串包装器不会得到我需要的值,如果我存储了字符串包装器,那将失败目的通过始终存储对密钥的强引用(防止从weakhashmap中删除密钥).
也许我只是不理解如何使用weakhashmap:S如果不是如何使用weakhashmap,我愿意接受其他如何做我想做的想法.
因此,Java WeakHashMap允许创建一个映射,如果其键变弱,则删除其条目.但是,当地图中的值变弱时,如何创建一个其条目被删除的Map ?我想使用地图的原因是全局哈希表,它根据ID来跟踪对象.
ID ---> Object Address
Key ---> Value
Run Code Online (Sandbox Code Playgroud)
(ID文字字符串在哪里)
我希望在对象地址变弱时删除键值对,而不是指向它们的字符串.有人对此有何看法?
我必须解决以下场景,在 Spring Security 中3.2.5-RELEASE,Spring Core 4.1.2-RELEASE应用程序在 Wildfly 8.1 上运行 Java 1.7。
我想把“鲍勃”踢出去
//this doesn't work
for (final SessionInformation session : sessionRegistry.getAllSessions(user, true)) {
session.expireNow();
}
Run Code Online (Sandbox Code Playgroud)我们有一个Scala服务器,它通过套接字使用Protocol Buffers获取节点树,我们需要将附加数据附加到每个节点.
在单线程上下文中,当节点树和关联数据同时删除其强引用时(由于超出范围),有没有理由使用带有weakKeys()的Google Guava的MapMaker而不是使用WeakHashMap ?似乎使用MapMaker,可以支付同步访问权限,在这种情况下不需要.
顺便说一下,如果MapMaker允许访问等价设置,那么可以选择引用相等但不关心弱引用或软引用.
WeakHashMap是Map接口的一个实现,如果相应的键不再被任何程序部分引用,Grabage Collector可以回收值对象的内存.因此,如果密钥不再用于程序中.它的Entry对象将被垃圾收集,无论其用途如何.它清晰到这里
这与HashMap不同,即使不再引用key,值对象仍保留在HashMap中.我们需要在HashMap对象上显式调用remove()方法来删除值.调用remove将只删除map中的条目.它对GC的准备将取决于它是否仍然在程序中的某个地方使用.
根据我的理解,在HashMap上使用WeakHashMap
我的理解是,只有当我们想要确保Grabage Collector在任何部分程序不再引用密钥时回收值对象时,我们才应该使用WeakHashMap.这使程序内存有效我的理解是正确的吗?
根据JavaDocs使用WeakHashMap ,我可以发现这个声明
此类主要用于密钥对象,其等于方法使用==运算符测试对象标识.
我没有得到上述声明的含义以及它与我对WeakHashMap用法的理解形成对比.实际上我没有得到这个陈述与WeakHashMap的使用有何关系?
更新: - 进一步仔细阅读下面的声明javadocs
当其密钥不再正常使用时,WeakHashMap中的条目将自动被删除.更准确地说,给定密钥的映射的存在不会阻止密钥被垃圾收集器丢弃,即,可以最终化,最终化,然后回收.当一个键被丢弃时,它的条目将被有效地从地图中删除,因此该类的行为与其他Map实现略有不同.
为了我和他人的利益,我正在修改我的理解
根据我的修订理解,在HashMap上使用WeakHashMap
我们应该只在我们想要确保在GC运行时从地图中删除键值对时才能使用WeakHashMap,而键不再是普通用途而不是map本身.
例如: -
WeakHashMap<Integer, String> numbers = new WeakHashMap<Integer, String>();
numbers.put(new Integer(1), "one");// key only used within map not anywhere else
numbers.put(new Integer(2), "two");
System.out.println(numbers.get(new Integer(1))); // prints "one"
System.gc();
// let's say a garbage collection happens here
System.out.println(numbers.get(new Integer(1))); // prints "null"
System.out.println(numbers.get(new Integer(2))); // prints "null"
Object key = new Object();
m1.put(key, c1);
System.out.println(m1.size());
key = null or new …Run Code Online (Sandbox Code Playgroud) WeakHashMap中的关键对象变得无法访问.并且应该在GC之后删除映射.但是对价值对象的强烈提及仍然存在.为什么?
使用番石榴弱键图可以观察到相同的行为.
预期产量:
...
refKey.get = null
refValue.get = null
Run Code Online (Sandbox Code Playgroud)
但我得到输出:
map.keys = []
map.values = []
map.size = 0
refKey.get = null
refValue.get = (123)
Run Code Online (Sandbox Code Playgroud)
码:
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
import com.google.common.collect.MapMaker;
public class Test {
static class Number {
final int number;
public Number(int number) { this.number = number; }
public String toString() { return "(" + number + ")"; }
}
static class Key extends Number {
public Key(int number) { super(number); }
}
static …Run Code Online (Sandbox Code Playgroud) 首先,我想澄清我对 的理解,WeakReference因为以下问题取决于相同。
static void test() {
Person p = new Person();
WeakReference<Person> person = new WeakReference<>(p);
p = null;
System.gc();
System.out.println(person.get());
System.out.println(person);
}
static class Person {
String name;
}
static class PersonMetadata {
String someData;
public PersonMetadata(String met) {
someData = met;
}
}
Run Code Online (Sandbox Code Playgroud)
上面代码的输出是
null
java.lang.ref.WeakReference@7852e922
这意味着虽然有一个实际的 person 对象在 GC 运行时被垃圾收集,但是WeakReference<Person>内存中存在一个类的对象,此时它不指向任何东西。
现在考虑到上述理解是正确的,我对它的WeakHashMap<K,V>工作原理感到困惑。在下面的代码中
public static void main(String[] args) {
Person p = new Person();
p.name = "John";
WeakHashMap<Person, PersonMetadata> map = new WeakHashMap<>(); …Run Code Online (Sandbox Code Playgroud) java collections garbage-collection weak-references weakhashmap
我读过许多人非常喜欢Google Guava(收藏集)的MapMaker,但是我看不出它有什么用处.
我已经阅读了javadoc,它说它的行为类似于ConcurrentHashMap.它还说new MapMaker().weakKeys().makeMap()几乎可以永远用作WeakHashMap的替代品.
但是,读取ConcurrentHashMap和WeakHashMap的javadoc 会让我想知道何时使用它是有用的?在我看来,你不能保证你在地图中放置的任何内容都会存在,或者我被误解了?
我的应用程序记录了某些对象的使用 - 我的设置使用AspectJ来识别我感兴趣的上下文并记录这些用法.我稍后加载日志文件进行分析,但出于效率原因,知道何时无法访问对象很有用.
我目前的方法是使用'垃圾记录器'记录我感兴趣的对象,然后创建一个包含对象标识哈希码的"saver"对象,并将其存储在弱哈希映射中.这个想法是,当收集对象时,将从弱哈希映射中移除保护对象并收集,从而运行代码以记录所收集对象的身份哈希码.我使用单独的线程和队列来防止在垃圾收集器中造成瓶颈.这是垃圾记录器代码:
public class GarbageLogger extends Thread {
private final Map<Object,Saver> Savings =
Collections.synchronizedMap(new WeakIdentityHashMap<Object,Saver>());
private final ConcurrentLinkedQueue<Integer> clearTheseHash =
new ConcurrentLinkedQueue<Integer>();
public void register(Object o){
Savings.put(o,new Saver(System.identityHashCode(o));
}
private class Saver{
public Saver(int hash){ this.hash=hash;}
private final int hash;
@Override
public void finalize(){
clearTheseHash.add(hash);
}
}
@Override
public void run(){
while(running){
if((clearTheseHash.peek() !=null)){
int h = clearTheseHash.poll();
log(h);
}
else sleep(100);
}
}
// logging and start/end code omitted
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,这似乎非常复杂,因为弱哈希映射不一定会清除它的条目,除非需要空间,我可能会在收集对象之前等待很长时间才能记录它.基本上,我正在寻找一种更好的方法来实现这一目标.
注意 - 我正在监视任意对象并且无法控制它们的创建,因此无法覆盖它们的终结方法.
我想测试Java WeakHashMap类功能,为此我编写了以下测试:
public class WeakHashMapTest {
public static void main(String args[]) {
Map<String, Object> weakMap = new WeakHashMap<>();
String x = new String("x");
String x1 = new String("x1");
String x2 = new String("x2");
weakMap.put(x, x);
weakMap.put(x1, x1);
weakMap.put(x2, x2);
System.out.println("Map size :" + weakMap.size());
// force all keys be eligible
x=x1=x2=null;
// call garbage collector
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Map size :" + weakMap.size());
System.out.println("Map :" + weakMap);
}
}
Run Code Online (Sandbox Code Playgroud)
运行WeakMapTest类后,我得到以下输出令人不快惊讶:
gc前的地图:{x = …
weakhashmap ×10
java ×9
guava ×3
hashmap ×2
caching ×1
collections ×1
data-loss ×1
data-storage ×1
spring ×1