7

当我的应用程序启动时,我正在使用 HashMap 来缓存一些重要数据。
此缓存有时会增长然后减少。我想知道它在 RAM 上占用了多少内存。
是否可以通过 KB 的地图获取内存?有API吗?

4

5 回答 5

13

我正在使用这种方法来估计 MAP 大小:

public static void size(Map map) {
    try{
        System.out.println("Index Size: " + map.size());
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(baos);
        oos.writeObject(map);
        oos.close();
        System.out.println("Data Size: " + baos.size());
    }catch(IOException e){
        e.printStackTrace();
    }
}
于 2012-10-04T03:30:57.910 回答
7

为此目的有一个很好的工具:ClassMexer

您可以通过以下方式估计 HashMap 的内存,包括引用的对象:

long noBytes = MemoryUtil.deepMemoryUsageOf(myCacheMap);

于 2012-07-04T13:24:59.830 回答
4

当然,您意识到您Map持有对在堆中存在的对象的引用,而不是对象本身。Map因此,如果不追查整个参考树以将键和值的字节相加,就问消耗了多少内存是没有意义的。

对象不这样做;没有办法实现它。

就像上面所说的明智评论一样,获取带有所有插件的 Visual VM 并配置您的应用程序。

于 2012-07-04T13:26:00.760 回答
3

在没有仪器的情况下,几乎不可能计算出对象的实际大小。

有时你可以根据指针的大小、原始类型、对象的开销等来计算它,但是对于像带有内容的 HashMap 这样复杂的东西(实际大小取决于它的历史和哈希因子以及它的所有元素都以哈希因子为模)几乎是不可能的。

唯一真正的解决方案是使用堆分析器,例如Eclipse Mat

于 2012-07-04T13:28:18.060 回答
1

这在很大程度上取决于您的 JVM 供应商和版本。您可以查看此演示文稿以进行粗略估计。

于 2012-07-04T13:29:33.097 回答