我有这堂课:
public class Stack {
private class Node {
String item;
Node next;
}
// some other methods here
}
在我的书中,作者说每个堆栈节点的大小是40个字节,包括:
16 bytes (object overhead)
8 bytes (inner class extra overhead)
8 bytes (references to string)
8 bytes (references to node)
----------------------------------------------
40 bytes per stack node
据我所知,最后两件事指的是String和Node的引用大小。但我不知道object overhead
和inner class extra overhead
对应的内容。你能解释一下吗?
答案 0 :(得分:6)
对象开销
每个对象都有一个标题,通常为8-12个字节。每个对象也是8字节对齐的,你说它的长度约为16个字节。
内部类额外开销
由于您的内部类不是静态的,因此它具有对外部类的引用。
如果这是一个匿名内部类,您可能拥有任意数量的最终变量的副本(在匿名类代码中使用的任何变量)
8个字节(内部类额外开销) 8个字节(对字符串的引用) 8个字节(对节点的引用)
大多数JVM使用32位引用,因此大小为4个字节。即使是堆高达32 GB的64位JVM也可以使用32位引用。
答案 1 :(得分:3)
首先:您引用的所有具体数字都是非常依赖于实现,并且根据您使用的JVM可能会有很大不同。
但是,大多数JVM都具有类似的值(例如,大多数JVM使用对象头)。
对象标头包含JVM需要跟踪对象的“簿记”信息。例如,它通常包含指示对象的确切类型的东西。
你所谓的“内部类额外开销”可能是指非静态内部类的每个实例都“绑定”到外部类的实例。您可以将其视为隐含字段,如下所示:private final Stack Stack_this
。实际上,您可以通过在Stack.this
的代码中引用Node
来实际使用该值。该implcit字段将占用与普通引用变量相同的内存量(通常为4或8个字节,具体取决于您的体系结构/ JVM)。
答案 2 :(得分:2)
在这里你可以找到答案: What is the memory overhead of an object in Java?
这里有一个更详细的答案:
Java中的对象内存使用情况: http://www.javamex.com/tutorials/memory/object_memory_usage.shtml
Java堆上的对象实例不仅占用了实际字段的内存。不可避免地,它们还需要一些“管家”信息,例如记录对象的类,ID和状态标志,例如对象当前是否可访问,当前是否同步锁定等。
答案 3 :(得分:2)
内部类的实例将根据正常规则进行垃圾收集(即,不再引用它们时)。但是,内部类的每个实例都包含对其外部类的父实例的隐藏引用。这意味着如果对内部类的实例有任何实时引用,它们将阻止外部类的关联实例被垃圾回收。但它只适用于那个方向,而不是相反。
答案 4 :(得分:1)
内部类具有对外部类的隐式引用,就好像它具有在构造函数中初始化的Stack outer
对象一样。该引用消耗了额外的8个字节,它允许您在内部类中使用Stack.this
。这是一个示例代码段:
public class Stack {
String item; // intentionally named the same as the one in the inner class
private class Node {
String item; // hides the field in the outer class!
Node next;
void doSomething() {
this.item = null;
Stack.this.item = null; // << note the reference to the outer instance
}
}
}
请注意,static
内部类不会产生这种开销,因为它没有指向外部对象的指针。
答案 5 :(得分:1)
任何特定对象的确切大小未在具体定义中 任何Java平台规范
未定义与对象关联的开销量,但为8 字节是典型的。
答案 6 :(得分:1)
首先,对象引用的值假定为64位JVM,在32位JVM上,引用使用4个字节。
对象开销是对象的标头,它包含有关JVM使用的对象的信息,通常为16个字节。
内部类是由于内部类保存对包含对象(Stack实例)的引用这一事实。
答案 7 :(得分:0)
我仍然不明白“每个堆栈节点40个字节”是什么意思。您知道当我创建新的Node实例时,我不会创建新的Stack实例。在创建新的Node实例时,如何将16bytes(对象开销)考虑在内?我也在跟踪算法,我在这里被迷惑了。