Java Wrapper & Primitive Memory Allocation



在一次采访中问了我以下问题

考虑以下代码

int i =0
Integer e1 = 0
它们将在哪个记忆中被创造?

根据我的理解

对于int i =0

基元数据类型进入堆栈内存和

对于Integer e1 = 0

Integer是一个包装类进入堆内存

请帮助正确理解?

这比这要复杂一些。

首先,您需要知道iei变量是局部变量还是对象1的字段(静态或实例)。

如果它们是局部变量:

  • i在堆栈上
  • ei在堆栈上(引用),它引用堆中的对象

如果它们是实例或类的字段:

  • i在堆上(作为实例或类的一部分)
  • ei在堆上(作为实例或类的一部分),它引用堆中的对象

最后,值得注意的是,Integer e1 = 0可能根本不分配新的Integer对象。存储在CCD_ 13中的引用可以是对已经存在的对象的引用。


1-还有另一种情况。如果iei是由内部类声明引用的局部变量,则在实例化内部类时将生成第二个副本。对于该副本,空间使用情况将如同i/ei是内部类的字段一样

这是一个非常有趣的问题。

对于原语,分配将在堆栈中,并将花费其所需的4个字节进行一些舍入。

但当谈到包装时,事情真的开始发展了。如果我们将其与C++进行比较,那么4个字节将在堆中分配,这使得e1成为一个指针。

假设我们使用的是64位机器,e1将在堆栈中占用8字节(+取整)。

堆数据块至少有一个4-8字节的小标头。

在这些类型的实现内部,我没有看到每个实例使用更多的内存,因为所有的辅助成员和常量都是静态的,所以所有实例都将在用于此类型的"数据段"中使用相同的数据块。

因此,添加所有这些表明包装器的分配将始终大于基元。例如,通过极其粗略的计算,你会得到这样的结果:

基元:int->4字节,包装器:整数->8(堆栈)+4+4=16字节

至于性能,似乎原语的操作速度要比包装器快得多,但这是另一个讨论。

希望这些信息能有所帮助。

最新更新