在一次采访中问了我以下问题
考虑以下代码
int i =0
Integer e1 = 0
它们将在哪个记忆中被创造?
根据我的理解
对于
int i =0
基元数据类型进入堆栈内存和
对于
Integer e1 = 0
Integer是一个包装类进入堆内存
请帮助正确理解?
这比这要复杂一些。
首先,您需要知道i
和ei
变量是局部变量还是对象1的字段(静态或实例)。
如果它们是局部变量:
i
在堆栈上ei
在堆栈上(引用),它引用堆中的对象
如果它们是实例或类的字段:
i
在堆上(作为实例或类的一部分)ei
在堆上(作为实例或类的一部分),它引用堆中的对象
最后,值得注意的是,Integer e1 = 0
可能根本不分配新的Integer
对象。存储在CCD_ 13中的引用可以是对已经存在的对象的引用。
1-还有另一种情况。如果i
或ei
是由内部类声明引用的局部变量,则在实例化内部类时将生成第二个副本。对于该副本,空间使用情况将如同i
/ei
是内部类的字段一样
这是一个非常有趣的问题。
对于原语,分配将在堆栈中,并将花费其所需的4个字节进行一些舍入。
但当谈到包装时,事情真的开始发展了。如果我们将其与C++进行比较,那么4个字节将在堆中分配,这使得e1成为一个指针。
假设我们使用的是64位机器,e1将在堆栈中占用8字节(+取整)。
堆数据块至少有一个4-8字节的小标头。
在这些类型的实现内部,我没有看到每个实例使用更多的内存,因为所有的辅助成员和常量都是静态的,所以所有实例都将在用于此类型的"数据段"中使用相同的数据块。
因此,添加所有这些表明包装器的分配将始终大于基元。例如,通过极其粗略的计算,你会得到这样的结果:
基元:int->4字节,包装器:整数->8(堆栈)+4+4=16字节
至于性能,似乎原语的操作速度要比包装器快得多,但这是另一个讨论。
希望这些信息能有所帮助。