如何使用Java linkedHashMap计算字节而不是条目

时间:2016-12-11 14:43:47

标签: java caching filesize linkedhashmap lru

此LRU缓存实现基于Java linkedHashMap

https://codereview.stackexchange.com/questions/80247/lru-cache-design-using-linkedhashmap

将removeEldestEntry中的逐出条件定义为size()> MAX_ENTRIES。 我宁愿需要一个面向字节的驱逐机制,例如bytesCached> MAX_SIZE(MAX_SIZE是缓存物理维度)。

如果例如,bytesCached> 100MB而不是size()> 50,那么如何逐出条目?

非常感谢。

的.m

1 个答案:

答案 0 :(得分:0)

可以有短而长的答案。

简短的回答是理论上可以计算存储在缓存中的每个对象占用的字节数,并计算它们的总和,以便知道何时驱逐对象。

答案越长,问题就越简单。的确想象你有这样的课:

class Simple {
    private int n;
    private byte b;
}

存储此类实例需要多少内存? 我们假设int为4个字节,byte为另一个字节,因此为5个字节。我们不计算存储对象本身的引用所需的内存。

这种情况很简单。但是以下内容如何:

class Simple2 {
    private int n;
    private byte b;
    private String s;
}

你现在需要多少记忆? 4+5+s.length*2?可能这是正确的。但String是类,因此s是引用。该引用可以在包括存储在同一缓存中的对象的其他对象中重用。你想要算两次吗?我不知道。

为简单起见,我们想要计算对象占用的整个内存。这意味着您应该递归地遍历对象并计算其成员占用的内存。这是一个复杂且性能极其昂贵的过程。

幸运的是,您可以使用其他技术。 Java instrumentation API允许估计对象占用的字节数。此外,还有一个项目http://sizeof.sourceforge.net/可以实现此功能并为您提供简单的API。

其他可能性是在对象实现Serializable时序列化对象,然后检查大小是否为serized对象。它甚至更昂贵,并且要求您的班级必须实施Serializable。另一方面,它不需要任何第三方依赖。