Java:final关键字的内存使用情况?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5621603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:57:15  来源:igfitidea点击:

Java: Memory usage of the final keyword?

javastaticmemory-managementfinal

提问by Detritus

When you declare a finalvariable (constant) in a class, for example:

在类中声明final变量(常量)时,例如:

private static final int MyVar = 255;

private static final int MyVar = 255;

How much memory will this require if I have 100,000 instances of the class which declared this?

如果我有 100,000 个声明这个的类的实例,这需要多少内存?

Will it link the variable to the class and thus have 1*MyVar memory usage (disregarding internal pointers), or will it link to the instance of this variable and create 100,000*MyVar copies of this variable?

它将变量链接到类并因此具有 1*MyVar 内存使用量(不考虑内部指针),还是链接到此变量的实例并创建此变量的 100,000*MyVar 副本?

Unbelievably fast response! The consensus seems to be that if a variable is both static and final then it will require 1*MyVar. Thanks all!

令人难以置信的快速响应!共识似乎是,如果一个变量既是静态的又是最终的,那么它将需要 1*MyVar。谢谢大家!

回答by Amir Rachum

The finalkeyword is irrelevant to the amount of memory used, since it only means that you can't change the value of the variable.

final关键字与使用的内存量无关,因为它仅意味着您不能更改变量的值。

However, since the variable is declared static, there will be only one such variable that belongs to the class and not to a specific instance.

但是,由于变量是声明的static,因此将只有一个这样的变量属于该类而不属于特定实例。

Taken from here:

取自这里

If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized . A field that is not declared static (sometimes called a non-static field) is called an instance variable. Whenever a new instance of a class is created, a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.

如果声明static了一个字段,则无论最终创建多少个类的实例(可能为零),都只存在该字段的一个化身。甲静态字段当类被初始化时,有时被称为一个类变量,被体现。未声明为静态的字段(有时称为非静态字段)称为实例变量。每当创建类的新实例时,都会为在该类或其任何超类中声明的每个实例变量创建与该实例关联的新变量。

回答by wesoly

There will be only 1*MyVar memory usage because it is declared as static.

只有 1*MyVar 内存使用量,因为它被声明为static.

回答by earcam

The static declaration means it will only have one instance for that class and it's subclasses (unless they override MyVar).

静态声明意味着该类及其子类只有一个实例(除非它们覆盖 MyVar)。

An int is a 32-bit signed 2's complement integer primitive, so it takes 4 bytes to hold it, if your example wasn't using static you'd just multiply that by the number of instances you have (for your example of 100,000 instances that's 0.38 of a megabyte - for the field alone, extra overhead for actual classes).

int 是一个 32 位有符号 2 的补码整数基元,因此它需要 4 个字节来保存它,如果您的示例不使用静态,您只需将其乘以您拥有的实例数(例如 100,000 个实例这是 0.38 兆字节 - 仅对于字段,实际类的额外开销)。

The final modifier on a field means it cannot be repointed to another value (whereas final on a class of method means it cannot be overridden).

字段上的 final 修饰符意味着它不能被重新指向另一个值(而方法类上的 final 意味着它不能被覆盖)。

回答by Thomas

It's static and thus class scope -> 1.

它是静态的,因此是类范围 -> 1。

Edit: actually, it depends on the class loaders. In the general case you have one copy of the class but if you have multiple class loaders/class repositories (might be the case in application servers etc.) you could end up with more.

编辑:实际上,这取决于类加载器。在一般情况下,您有一个类的副本,但如果您有多个类加载器/类存储库(可能是应用程序服务器等的情况),您最终可能会得到更多。

回答by axtavt

In addition to the fact that staticfields belong to their classes, and thus there is only one instance of staticvaraible per class (and per classloader), it's important to understand that static finalvariables initialized by compile-time constant expressions are inlined into classes that use them.

除了static字段属于它们的类这一事实之外,因此static每个类(和每个类加载器)只有一个varaible实例,重要的是要了解static final由编译时常量表达式初始化的变量被内联到使用它们的类中

JLS §13.1 The Form of a Binary:

JLS §13.1 二进制的形式

References to fields that are constant variables (§4.12.4) are resolved at compile time to the constant value that is denoted. No reference to such a constant field should be present in the code in a binary file (except in the class or interface containing the constant field, which will have code to initialize it), and such constant fields must always appear to have been initialized; the default initial value for the type of such a field must never be observed.

对作为常量变量(第 4.12.4 节)的字段的引用在编译时解析为所表示的常量值。二进制文件的代码中不应出现对此类常量字段的引用(包含常量字段的类或接口除外,它们将具有初始化它的代码),并且此类常量字段必须始终显示已初始化;绝不能遵守此类字段类型的默认初始值。

So, in practice, the instance of static finalvariable that belong to its class is not the only instance of value of that variable - there are other instances of that value inlined into constant pools (or code) of classes that use the variable in question.

因此,在实践中,static final属于其类的变量实例并不是该变量值的唯一实例——该值的其他实例被内联到使用相关变量的类的常量池(或代码)中。

class Foo {
    public static final String S = "Hello, world!";
}

class Bar {
    public static void main(String[] args) {
        // No real access to class Foo here
        // String "Hello, world!" is inlined into the constant pool of class Bar
        String s = Foo.S; 

        System.out.println(s);
    }
}

In practice it means that if you change the value of Foo.Sin class Foo, but don't recompile class Bar, class Barwill print the old value of Foo.S.

实际上,这意味着如果您更改了Foo.Sclass 中的值Foo,但不重新编译 class Bar,则 classBar将打印 的旧值Foo.S

回答by Harsha

The keyword "final" helps you to declare a constant with a specific amount of memory, where as the keyword "static" as its prefix will gives a single instance of this constant, what ever be the amount of memory consumed...!!!

关键字“final”可帮助您声明具有特定内存量的常量,而作为前缀的关键字“static”将提供此常量的单个实例,消耗的内存量是多少......! !

回答by dantuch

staticmeans you will have only one instatnce

静态意味着您将只有一个实例

finaljust means, that you can't reassign that value.

final只是意味着,您不能重新分配该值。

回答by janhink

The crucial part here is that you declared the variable as staticbecause static variables are sharedamong all instances of the class, thus requiring only as much space as one instance of the variable. Declaring a variable finalmakes it immutable outside its declaration or constructor.

这里的关键部分是您将变量声明为static因为静态变量在类的所有实例之间共享,因此只需要与变量的一个实例一样多的空间。声明变量final使其在其声明或构造函数之外不可变。

回答by tcooc

finalmakes is 1*instancesmemory usage.

finalmake 是1*instances内存使用情况。

However, staticmakes it simply 1.

然而,static让它变得简单1

回答by Peter Lawrey

You will have one instance per class. If you have the class loaded more than once (in different class loaders) it will be loaded once per class loader which loads it.

每个类将有一个实例。如果您多次加载该类(在不同的类加载器中),它将为每个加载它的类加载器加载一次。

BTW: Memory is surprising cheap these days. Even if there was a copy per instance, the time it takes you to ask the question is worth more than the memory you save. You should make it static finalfor clarity rather than performance. Clearer code is easier to maintain and is often more efficient as well.

顺便说一句:现在内存出奇的便宜。即使每个实例都有一个副本,您提出问题所花费的时间也比您节省的内存更有价值。你应该static final为了清晰而不是性能而制作它。更清晰的代码更易于维护,而且通常也更高效。