Java: Memory usage of the final keyword?

12,495

Solution 1

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.

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.

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.

Solution 2

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

Solution 3

The static declaration means it will only have one instance for that class and it's subclasses (unless they override 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).

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).

Solution 4

It's static and thus class scope -> 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.

Solution 5

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.

JLS §13.1 The Form of a Binary:

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.

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.

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.

Share:
12,495

Related videos on Youtube

Detritus
Author by

Detritus

Updated on July 12, 2020

Comments

  • Detritus
    Detritus almost 4 years

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

    private static final int MyVar = 255;

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

    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?

    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!

    • DaveH
      DaveH about 13 years
      It is the fact that it is static that is important in terms of memory allocation. Final has no bearing upon it
  • Joachim Sauer
    Joachim Sauer about 13 years
    To clarify: final has no effect on the memory requirement. static does have an effect.
  • Stephen C
    Stephen C about 13 years
    +1 - though 1 is going to be 4 bytes or 8 bytes depending on the actual JVM used. (On a 64-bit JVM, you could end up wasting 4 bytes due to word alignment issues.)
  • Detritus
    Detritus about 13 years
    Memory maybe cheap, however, when you have limited resources of which you have no control upon. The price of memory is irrelevant.
  • Travis Webb
    Travis Webb about 13 years
    One extra note on this: this is per JVM, so if your program has multiple processes this may not apply.
  • earcam
    earcam about 13 years
    Not per JVM, per classloader - Good answer from Thomas (below) in JEE environments using isolated classloaders the class could be loaded many times. Also in OSGi multiple versions of the same class could be loaded, or in Virgo etc by using application partitioning.
  • Vishy
    Vishy about 13 years
    Say you have a storage limited mobile device, you wouldn't create 100,000 copies of anything without a great deal more thought. In any case only the static variable determines that there is one copy per class. The final is for clarity.
  • user85421
    user85421 about 13 years
    Why multiply by the number of instances if it is static, that is, once per classs?
  • Detritus
    Detritus about 13 years
    I never said a mobile device, I simply said a limited resource. Keeping my objects in RAM makes my software very responsive. My goal is to maximise the number of objects I can keep in RAM. Currently that number is > 4,000,000. 100,000 was simply an arbitrary number. This is not for any commercial applications, this is for one-time run simulations where speed is critical.
  • Vishy
    Vishy about 13 years
    If speed/memory is critical I suggest you run a small sample of data in a profiler to see how much memory you use. The reason I said memory was cheap is that you can buy a server with 8 GB for around $550. (Even 4m x 4 bytes is 16MB) I assume you have no money to spend on upgrades. In that case it is worth spending more time with your profiler.
  • earcam
    earcam about 13 years
    Agreed, was unclear to the point of misleading; edited to include "... if your example wasn't using static you'd just multiply that by ..."
  • Jemshit Iskenderov
    Jemshit Iskenderov about 7 years
    What if i have class that i hold constant variables with static final and only use those variables without creating instance of class. Will those constant variables be held in memory even if i don't use them when app is started? (or in stack since variables are primitive)