有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Java中,每个共享引用是否占用另一个内存字(例如32或64位)?

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

例如

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

?

此外,如果我有一个HashMap<Character, Character>,其中我总是输入与key和value完全相同的Character对象,那么它是否占用了HashSet<Character>中引用的两倍内存加上Characters本身的内存量,即使每次对key和value都使用相同的对象引用?我知道这可能与第一个问题相同,但我想知道这个案例的表现是否会有所不同

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


共 (6) 个答案

  1. # 1 楼答案

    基本上,如果有多个引用,每个引用都会占用单独的内存,而不管它指向哪里

  2. # 2 楼答案

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

    does it take up double the memory of the references

    不是。HashSet是HashMap的包装器,所以它消耗相同的内存量

    In each of these cases, if the root objects are static, are the references stored on the stack or the heap?

    静态字段总是存储在HotSpot中的堆上,但如果在JLS中没有指定,则可能会有所不同。把它放在堆栈上是没有意义的,因为它是线程本地的

  3. # 3 楼答案

    是的,你有3个参考,所以它是参考内存的3倍

    Character对象获取引用的内存及其内容(例如,char)。一个char原语只会占用原语的空间(这比64位系统上的引用要小)。如果将相同的对象用作键和值,那么可以查看两个引用和一个对象

  4. # 4 楼答案

    将对象想象成数据库表中的一行:对于给定列,两行是否具有相同的值并不重要:仍然必须将值保存在特定行中,因此,如果两个用户共享名称John,则表将增长为托管两个John:)

    +------------------------------+
    |   ID   |        NAME         |
    +--------+---------------------+
    |0x76BA39|       John          |
    +--------+---------------------+
    |0xB4H821|       John          |
    +--------+---------------------+
    
  5. # 5 楼答案

    对象x、对象1、对象2和对象3将在堆上分配一次。最后三个对象中的每一个都将通过引用引用实例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).

  6. # 6 楼答案

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

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

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