关于内存分配的几个问题

时间:2014-11-14 22:32:33

标签: java memory-management

我尝试找到它,但我没有合适的术语知识,也无法在Google上提出正确的问题。

首先:我正在创建一个类似于Tree的结构,其中一个Object包含子映射,对于child和next也是如此...

public class Attribute
{
    private String key;
    private int value;
    private HashMap<String, Attribute> modifiers;

    public Attribute(String key, int value)
    {
        this.key = key;
        this.value = value;
    }
}

MODIFIERS仅在您实际放入内容时进行初始化(使用local void method ofc)。 J HashMap在JUST声明中使用了多少内存(如果是)(如上面的代码所示)?

第二:玩家是.c。存储玩家所有数据的玩家对象。

public class Something
{
    private Player player;

    public Something() {}

    public Something(Player player)
    {
        this.player = player;
    }
}

1:类似的问题,如果我调用Something(),是不是初始化的PLAYER对象使用了一些内存,多少钱?我在某处读到,当你声明'某事'时,会根据这个'某事'的类型来分配记忆。但它如何与对象一起使用?

2:如果我调用Something(播放器播放器),并且由于我正在引用已存在的对象,此引用使用了多少内存? (this.PLAYER =玩家) 我猜这样的引用就像指针一样,但它使用了多少内存,对于Java中的所有对象都是常量吗?

3 个答案:

答案 0 :(得分:1)

这取决于VM。在大多数情况下 - 对于32位Oracle JVM或64位Oracle JVM 7+实例,堆空间小于~32GB - 它将增加4个字节。

空间使用是相同的,无论它是null还是引用一个对象(尽管显然引用的对象有自己的空间要求)。

这是Oracle's tech notes on JavaSE 7 JVM enhancements的副本:

  

压缩哎呀

     

Java Hotspot用语中的&#34; oop&#34;或普通对象指针是指向对象的托管指针。 oop通常与本机指针的大小相同,这意味着LP64系统上的64位。在ILP32系统上,最大堆大小略小于4千兆字节,这对于许多应用程序来说是不够的。在LP64系统上,给定程序使用的堆可能必须比在ILP32系统上运行时大1.5倍。此要求是由于托管指针的扩展大小。内存很便宜,但是现在带宽和缓存供不应求,因此显着增加堆的大小并且仅仅超过4千兆字节的限制是不可取的。

     

Java堆中的托管指针指向在8字节地址边界上对齐的对象。压缩的oops表示托管指针(在JVM软件中的许多但不是所有位置)作为来自64位Java堆基址的32位对象偏移量。因为它们反对偏移而不是字节偏移,所以它们可以用于处理多达40亿个对象(不是字节),或者堆大小最多大约32千兆字节。要使用它们,必须将它们缩放8倍并添加到Java堆基址以查找它们引用的对象。使用压缩oops的对象大小与ILP32模式中的对象大小相当。

     

术语decode用于表示将32位压缩oop转换为64位本机地址到托管堆中的操作。逆操作称为编码。

     

默认情况下,Java SE 6u23及更高版本支持并启用压缩的oops。在Java SE 7中,当未指定-Xmx且-Xmx值小于32千兆字节时,使用压缩oops是64位JVM进程的缺省值。对于6u23发行版之前的JDK 6,请使用-XX:+ UseCompressedOops标志和java命令来启用该功能。

答案 1 :(得分:0)

由于你的Hashmap是一个参考,它的内存消耗取决于你的架构的参考大小(32位为4字节,64位为8字节)

查看以下链接:

答案 2 :(得分:0)

对象占用一些(应该在32左右,但在很大程度上取决于JVM版本,系统......)字节在内存中,即使你创建了一个非常空的new Object()

class SomeClass {
    Object someField;
}

如果向该类添加字段,则该对象的每个实例都需要有空间来额外引用另一个对象。引用大致是一个内存地址,应该需要4或8个字节。引用对象的大小并不重要。

class SomeClass {
    Object someField = new Object();
}

如果实际引用另一个对象,则对象的大小保持不变。引用的值不再是&#34; 0&#34;,它指向一些实际的对象。

但是你显然会消耗更多的内存,因为引用的对象也需要在内存中。

  

如果我致电new Something()

您将分配1 Something个对象,其大小为Basic Object + 1 x Reference。 Java永远不会自动创建Player对象。你必须告诉它这样做。

  

如果我拨打new Something(Player player)

你会得到与上面相同的东西,只是存储在参考中的值现在指向一些有用的东西。它实际上只是一个4字节的数字字段,最后有所不同。

相关问题