通过保存自定义对象的哈希图测量或至少在某种程度上准确估计总内存消耗的最佳选择是什么?
背景:
我们的系统有多个内存存储(ConcurrentHashMap's),其中存储着不同类型的1K-200K对象。我们希望定期监视这些内存的占用空间。
约束/期望:
我们无法承受频繁的GC或这些哈希图的完整迭代,这会对延迟产生负面影响。据我所知,java中没有sizeof(),所以我们可以估计。
考虑以下选项:
有一个线程通过以下方式报告每个哈希图的内存使用情况#
答案 0 :(得分:2)
首先,有this(Alexey Shipilev)(甲骨文公司前JVM工程师,现为Redhat的一名出色文章)解释说,这不是那么容易。
> Java中的每个对象都有两个标头,它们的大小可以取决于平台或jvm以(UseCompressedOops
开始的配置。
然后,在字段和对象自身之间进行填充和对齐(8字节对齐)。然后,有一个JVM根本不会显示的空间,因为它不能显示或确实需要显示。
所有这些事情使得计算某个对象在堆中的大小变得有些微不足道。幸运的是JOL存在。它甚至也有很多示例...这是一个小示例,假设您有这样的类:
static class MyValue {
private final int left;
private final String right;
public MyValue(int left, String right) {
this.left = left;
this.right = right;
}
}
然后您创建一个HashMap
:
Map<String, MyValue> map = new HashMap<>();
System.out.println("empty map = " + GraphLayout.parseInstance(map).totalSize());
MyValue one = new MyValue(1, "one");
System.out.println("one = " + GraphLayout.parseInstance(one).totalSize());
map.put("one", one);
System.out.println("map after one = " + GraphLayout.parseInstance(map).totalSize());
MyValue two = new MyValue(1, "two");
map.put("two", two);
System.out.println("map after two = " +
GraphLayout.parseInstance(map).totalSize());
答案 1 :(得分:1)
如果我的理解是正确的,那么您想知道并发HashMap的大小。我认为,以下步骤可能会有所帮助。
其他选项是使用Profiler之类的JProfiler来查看对象图及其大小。