未初始化的原始实例变量是否使用内存?

WVr*_*ock 42 java primitive memory-management initialization

在Java中,在没有初始化的情况下声明类级实例变量会花费内存吗?
例如:int i;如果我没有初始化它,是否使用任何内存i = 5;

细节:

我有一个巨大的超级类,许多不同的(没有足够的不同,有自己的超类)子类扩展.一些子类不使用超类声明的每个单元.我可以简单地将这些原语保留为未初始化,并仅在必要的子类中初始化它们以节省内存吗?

Era*_*ran 72

您的类中定义的所有成员都具有默认值,即使您没有显式初始化它们,因此它们也会使用内存.

例如,int默认情况下每个都将初始化为0,并将占用4字节.

对于班级成员:

int i;
Run Code Online (Sandbox Code Playgroud)

是相同的 :

int i = 0;
Run Code Online (Sandbox Code Playgroud)

以下是JLS关于实例变量的内容:

如果类T具有作为实例变量的字段a,则创建新的实例变量a并将其初始化为默认值 (第4.12.5节),作为每个新创建的类T对象的一部分或任何类的一部分. T的子类(第8.1.4节).在完成对象(第12.6节)的任何必要的最终化之后,当实例变量不再被引用时,实例变量实际上不再存在.

  • @sᴜʀᴇsʜᴀᴛᴛᴀ空引用Object-Type属性将占用32/64位,即使它为null,因此它与int = 0基本相同.参考永远不会占用更多空间!只会添加新对象的额外分配空间....但是用java classloader讨论这个问题,并且所有内容都是99%的过早优化,并且没有任何好处...... (4认同)
  • @spoko Singletons是具有单个实例的类.使用延迟初始化时,持有该实例的变量包含空引用.只有在实例化类时,才会为实例分配内存. (3认同)
  • @spoko Primitives!=类.Primitives默认分配内存.但不是为了参考.它们保持默认值"null". (3认同)
  • @Eran今天我在波兰维基百科上阅读"Singleton"(波兰语用户http://pl.wikipedia.org/wiki/Singleton_(wzorzec_projektowy)#Konsekwencje_stosowania).根据这篇文章,使用单例的一个优点是"由于延迟初始化,如果没有使用单例的组件,则不会给单例的实例提供任何资源".单身人士不是原始类型,我知道,但是他们没有一些默认值吗?是真的,他们在初始化之前不使用任何内存吗? (2认同)

Sur*_*tta 17

是的,内存分配虽然您没有为其分配任何值.

int i;
Run Code Online (Sandbox Code Playgroud)

这需要32 bit记忆(分配).无论你是否使用它.

有些子类不使用超类声明的每个基元.我可以简单地将这些原语保留为未初始化,并仅在必要的子类中初始化它们以节省内存吗?

同样,无论您在何处初始化,内存都会分配.

只需要注意的是,只需找到未使用的基元并将其删除即可.

编辑: 添加一个与默认值不同于原始引用的点null,它带有一个内存

 4 bytes(32-bit) 
 8 bytes on (64-bit)
Run Code Online (Sandbox Code Playgroud)


Bar*_*W19 11

最初的问题是关于类级变量,答案是它们确实使用了空间,但是看看方法范围的变量也很有趣.

我们举一个小例子:

public class MemTest {
    public void doSomething() {
        long i = 0;  // Line 3
        if(System.currentTimeMillis() > 0) {
            i = System.currentTimeMillis();
            System.out.println(i);
        }
        System.out.println(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我们看一下生成的字节码:

  L0
    LINENUMBER 3 L0
    LCONST_0
    LSTORE 1
Run Code Online (Sandbox Code Playgroud)

好的,正如预期的那样,我们在代码中的第3行分配一个值,现在如果我们将第3行更改为(并因编译器错误而删除第二个println):

long i; // Line 3
Run Code Online (Sandbox Code Playgroud)

...并检查字节码,然后没有为第3行生成任何内容.因此,答案是此时没有使用内存.事实上,当我们分配给变量时,LSTORE仅在第5行发生.因此,声明未分配的方法变量不会使用任何内存,实际上也不会生成任何字节码.它相当于在您首次分配声明时进行声明.

  • 没有生成的原因是因为编译器足够智能以优化它.否则,未初始化(和未使用)的局部变量会占用内存. (2认同)

Ruc*_*era 6

是.在您的类级别变量将分配其默认值,即使您没有初始化它们.

在这种情况下,您int将为每个变量分配0并占用4 bytes它们.