1

假设 3 个对象每个都有一个 object 的引用x,这 3 个引用中的每一个是否占用另一个内存字(例如 32 或 64 位,意味着总共 96 或 192 位),即使它们都已设置为同一个对象?

例如

X x = getX();
object1.x = x;
object2.x = x;
object3.x = x;

?

此外,如果我有一个HashMap<Character, Character>,我总是输入完全相同的Character对象作为键和值,它是否会占用双倍的引用内存HashSet<Character>加上Characters它们自己的内存量,即使相同的对象引用是每次都用于键和值?我知道这可能与第一个问题相同,但我想知道这种情况的行为是否会有所不同?

在每种情况下,如果根对象是static,那么引用是存储在堆栈还是堆中?

4

6 回答 6

1

是的,你有 3 个引用,所以它是引用内存的 3 倍。

Character对象获取引用的内存及其内容(例如 a char)。char原语只会消耗原语的空间(比 64 位系统上的引用少)。如果您使用相同的对象作为键和值,那么您将查看两个引用和 1 个对象。

于 2012-12-03T22:11:49.370 回答
1

基本上,如果您有多个引用,则每个引用都会占用单独的内存,而不管它指向何处。

于 2012-12-03T22:09:59.477 回答
0

对象 x、object1、object2 和 object3 将在堆上分配一次。最后三个对象中的每一个都将通过引用引用实例 x。除了引用属性(假设它们没有任何其他属性)之外,这些对象中的每一个都不需要额外的内存。通常,每个对象占用的空间取决于其属性。每个分配的对象还需要 jvm 一个标头,通常包括一个标记字、类元数据,如果实例是一个数组,它的长度(参见http://www.cs.princeton.edu/picasso/mats/HotspotOverview.pdf)。

静态定义的类属性在类初始化阶段(http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html)位于永久代(热点中)的类定义中分配#jvms-5.5)。

于 2012-12-03T22:18:32.043 回答
0

将对象想象成数据库表中的一行:对于给定列,两行是否具有相同的值无关紧要:仍然必须将值保存在特定行中,所以如果两个用户共享名称John ,则可以,您的桌子可以容纳两个约翰的 :)

+------------------------------+
|   ID   |        NAME         |
+--------+---------------------+
|0x76BA39|       John          |
+--------+---------------------+
|0xB4H821|       John          |
+--------+---------------------+
于 2012-12-03T22:13:00.283 回答
0

在您编写的代码中,没有消耗尚未消耗的额外内存。您只是在更改引用object1.xobject2.x和的内容object3.x

在当前的 JDK 中,aHashMap<Character, Character>将占用与HashSet<Character>相同大小的 a 相同的内存量。(实际上稍微少一点。)这与它是否将字符映射到自身无关。

只有方法局部引用变量存储在堆栈中;其他所有内容都存储在堆上。特别是,任何对象的字段(无论是否static存在)都将像对象的其余部分一样存储在堆上。

于 2012-12-03T22:09:19.113 回答
0

引用总是占用相同数量的内存,通常是 32 位,即使在 64 位 JVM 上也是如此。它不会因为它引用同一个对象作为另一个引用而变得更小。

它是否占用了引用内存的两倍

不。HashSet 是 HashMap 的包装器,因此它消耗相同数量的内存。

在每种情况下,如果根对象是静态的,那么引用是存储在堆栈还是堆中?

静态字段始终存储在 HotSpot 的堆中,但 AFAIK 未在 JLS 中指定它,因此它可能会有所不同。将它放在堆栈上是没有意义的,因为这是线程本地的。

于 2012-12-03T22:09:44.297 回答