简体   繁体   English

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

[英]Java: Memory usage of the final keyword?

When you declare a final variable (constant) in a class, for example: 在类中声明final变量(常量)时,例如:

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. 共识似乎是,如果变量既是静态的又是最终的,那么它将需要1 * MyVar。 Thanks all! 谢谢大家!

The final keyword 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. 如果一个字段被声明为static ,那么无论该类最终可以创建多少个实例(可能为零),都只存在该字段的一个化身。 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. 每当创建一个新的类实例时,就会为该类或其任何超类中声明的每个实例变量创建一个与该实例关联的新变量。

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

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意味着它不能被覆盖)。

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. 在一般情况下,您有一个类的副本,但如果您有多个类加载器/类存储库(可能在应用程序服务器等情况下),您可能会得到更多。

In addition to the fact that static fields belong to their classes, and thus there is only one instance of static varaible per class (and per classloader), it's important to understand that static final variables initialized by compile-time constant expressions are inlined into classes that use them . 除了static字段属于它们的类这一事实之外,因此每个类(以及每个类加载器)只有一个static变量实例,重要的是要理解由编译时常量表达式初始化的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. 对作为常量变量的字段(第4.12.4节)的引用在编译时被解析为表示的常量值。 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. 绝不能遵守此类字段类型的默认初始值。

So, in practice, the instance of static final variable 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.S in class Foo , but don't recompile class Bar , class Bar will print the old value of Foo.S . 实际上,这意味着如果在类Foo更改Foo.S的值,但不重新编译类Bar ,则类Bar将打印Foo.S的旧值。

关键字“final”可以帮助您声明具有特定内存量的常量,其中关键字“static”作为其前缀将给出此常量的单个实例,即消耗的内存量... !! !

static means you will have only one instatnce 静态意味着你将只有一个生命

final just means, that you can't reassign that value. 最后只是意味着你不能重新分配这个价值。

The crucial part here is that you declared the variable as static because static variables are shared among all instances of the class, thus requiring only as much space as one instance of the variable. 这里的关键部分是您将变量声明为static因为静态变量在类的所有实例之间共享 ,因此只需要与变量的一个实例一样多的空间。 Declaring a variable final makes it immutable outside its declaration or constructor. 声明变量final会使其在声明或构造函数之外不可变。

final makes is 1*instances memory usage. final make是1*instances内存使用量。

However, static makes it simply 1 . 但是, static使它只是1

Static means, one instance per class, static variable created once and can be shared between different object. 静态意味着,每个类一个实例,静态变量创建一次,并且可以在不同对象之间共享。

Final variable, once value is initialized it can't be changed. 最终变量,一旦初始化值,就无法更改。 Final static variable use to create constant (Immutable) and refer directly without using the object. 最终的静态变量用于创建常量(Immutable)并直接引用而不使用该对象。

它是静态的,因此只会创建一个实例,因此需要分配许多字节来保存一个int原语

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 final for clarity rather than performance. 为了清晰而不是表现,你应该把它作为static final Clearer code is easier to maintain and is often more efficient as well. 更清晰的代码更易于维护,并且通常也更有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM