Memory scope of static variables - java

I have a class defined as follows
final public class Results {
THashSet<String> filteredHashtags;
Constraints: I know that declaring a variable as static or non-static is a design problem and shouldn't be governed by memory usage but the HashSet filteredHashtags takes up significant memory (>1Gb) so I can afford slightly lower readability at the cost of lower memory usage.
Options
Non-static: As of now I've kept it non-static for the following reason: I create an instance of class, use constructor to assign value to filteredHashtags. Since I'm creating only one instance of the class, it doesn't really mater in terms of memory used by the class. When the object is no longer referred, the memory used by the variable gets freed.
Static: In terms of readability of code, I would prefer keeping it static as it relates better to the physical quantity it represents. However in this case, I need to assign value to the static variable using a function, let's say setValues(...).
Questions:
Is my assumption that in the static case, the memory associated with the variable will never be freed until the program terminates?
If yes, is there a better way to free memory other than setting filteredHashtags = null;

Rishi, your assumption that 'in the static case, the memory associated with the variable will never be freed until the program terminates' is not correct.
Static belongs to the class, and classes are loaded by loaders. Hence, memory used by static variables can be reclaimed.

Related

Instance variable of a static nested class vs static variable of an outer class

I was using a static nested class in java for a particular use-case. A minimal example of the same is shown below:
public class Foo {
static int fooInner = getInner(); // CASE 1
private static class StaticFoo {
int fooInner = getInner(); // CASE 2
public int useFooInner(){
System.out.println(fooInner);
//do something
}
}
}
The question is how is the memory allocation in Case 1 different from that in case 2? Or is it the same?
What if I make the case 2 variable static too. Will the memory usage differ?
NOTE: Please do not mention that shadowing will take place. Although I have put both the variables there, but it's an "OR" case and that's why the "CASE"s.
PS: I feel that the memory usage should be the same. Since the nested class is static, it won't be created for every object and thus the instance variable fooInner (Case 2) will also be created just once. Thus, the getInner() function would run just once. But it is just at an abstract level + gut feeling. A more descriptive answer would be appreciated!
They are different.
From a memory allocation point of view, a static inner class is no different from a top level class. Your StaticFoo will be compiled to a class (Foo$StaticFoo.class) that is essentially independent from its parent class at runtime. At compile time, there are access checks for private members.
So, in case 1, you have a static field in a class. It will be allocated as a field on a Foo.class object on the heap. There will only be one instance per ClassLoader that loads the Foo class, which generally means just one shared instance for the whole JVM.
In case 2, you have an instance field in the Foo$StaticFoo class. On the heap, there will be space allocated (and a value assigned) for (and in) each instance of StaticFoo created. Each StaticFoo that gets created will access its own instance of that field, and since it's not final, the value of each instance can be independently changed.
If you changed StaticFoo.fooInner to be static, then it would be exactly the same as case 1.
Note: The above is true only for Java 8 and later. For earlier JVMs, that amount of memory allocated in each case still matches the description above, but static variables, as well as being singletons per ClassLoader, are also stored in a different memory pool: PermGen Space rather than the main heap. See this answer for more details.

Could using final on local variables (NOT class declarations or class members) cause memory leak?

From a naive point of view, it looks like declaring a local variables (ie., variables inside a method) as "final" could cause memory leak.
Eg.,
public static MyObject create()
{
final Long time = System.millis();
return new MyObject()
{
#Override public Long getTime() {return "Time is: " + time ; }
}
}
Clearly, the time field has to be kept around even when create() has returnt in order for getTime() to work.
Ok, now say I have this method
public static int create()
{
final Long time = System.millis();
System.out.println(time);
return 2;
}
time is not referenced in any inner class.
Is the object kept around after the method returns? Y
Thanks,
The object you are returning stores the value it has to return. I wouldn't call this a memory leak, as this is what you intended the code to do. A memory leak is an undesirable waste of memory.
A more significant potential for memory leak is if you make the method non-static. In this case a reference to the outer class is retained and all it's data even though you clearly don't need it.
Is the object kept around after the method returns?
The object can be cleaned up after it is passed to println(). When/if it is cleaned up depends on the GC, but this is not considered a memory leak.
In your case, there is an anonymous Class created by compiler and this class reference to has a Field that implicitly reference to Long object instance (that referenced by 'time' variable).
The memory of Long Object that referenced by 'time' variable is ON Java Heap memory. This Long object memory will have the same lifecycle with the instance of Anonymous created. SO -- No memory leak here.
For Case2: Long object memory will exists for a while even the 'create' method is DONE because this memory is on Heap. This memory will not destroyed until Next Garbage Collector run ------- SO No memory leak here.
NOTE:
I am answering in general case. In the real world. Long Object can be POOLED if its value from -127 to 128. In this case Long Object that referenced by variable 'time' may have the same Lifecycle with Your whole application (JVM instance)

How many copies of a static final property are stored in memory when I have a collection of their classes

Suppose I have this simple class:
public class Car {
public static final int TYPE_SUV = 1;
public static final int TYPE_TRUCK = 2;
public String name;
public int carType;
}
Now if I have a collection of these, I know that I am allocating a String and an int for each element in the collection, but am I also storing static ints multiple times? This contrived example class is representative of the kind of Java I wrote years ago before I learned that magic numbers like this are better served with an enum which is defined in a separate class, but I've always wondered what the side effect of this code is.
From the 1.7 JLS:
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 (§12.4).
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 (§12.5), a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.
The key point to note is that memory is consumed on a per-class (not instance) basis, irrespective of how many instances you have (1, 1000 or none).
For what it's worth:
Your name and carType instance variables are only allocated when an instance is created. What's more, before java 7, Strings of an equal value could be interned - maintained in a single String instance that is referenced wherever used - into a String-managed memory (in PermGen). This changed with java 1.7 when it was moved to the main heap and seems to be changing again(?) with java 8
No copies are stored anywhere, multiple references to the same location in memory (on the heap ) are created.
static variable are related to class not with Object. So as many Object you create but static variable will be once get spaced in memory and all the Static context loads at class loading time so without creating Object also you can access your static variable with the help of class name.
No multiple copies of static is maintained. all objects have same static variables. If they have it then you have to access them using object but this is not what we do with static.
The Penalty of storing references = penalty of creating the class.

where static objects are stored in java

I'm reading a book "Thinking in Java" which says
objects are stored on heap and static variable on stored on some fixed location say static storage so that they can be available for entire time program is running.
class Myclass{
static int x =0; //stored on static storage
Myclass obj = new Myclass(); //stored on heap
}
Although making a object, static will not be a good idea as far as OOPS is concerned. Putting this aside for a while. there comes my questions that
where does object which is declared static is stored.
how does JVM does instantiation in this case.
class Myclass { static Myclass obj = new Myclass(); //no man's land }
All static content will be created on class load/initiation and stored in special location (most probably part of perm gen, differs based on implementation).
For second example, When your Myclass is loaded, it's static content will be created/instantiated.
This tutorial may give you high level overview.
Static is a special memory location to the program. So the program could easily access it. Only one such location available for the program to run. And it's the place where static content is created. The JVM instantiates objects on the heap. But if you make a static reference to the object then it placed in the static memory place.
static variables are stored on method area.
method area is part of non-heap memory. It stores per-class structures, code for methods and constructors. Per-class structure means runtime constants and static fields.
It depends on JVM implementation. In your example the variable is initialized to a primitive value and so it will be stored in metaspace(native memory, offheap). In case you initialized it with new ObjectClassSmthng() the object will be stored on heap and x variable (which is a reference) would be stored in metaspace.
This is true for HotSpot JDK 8.

Performance differences between static and non-static final primitive fields in Java

I recently ran across a class that had the following field declared:
private final int period = 1000;
In this particular case, the author had intended for it to also be static and since the value couldn't be altered at any point, there was no real functional reason not to declare it static, but it got me wondering how Java treats final vs. final static primitives.
In particular:
1) How are final static primitives stored? Are they simply compiled directly into the expressions in which they're used?
2) If they are actually allocated storage, does each instance of the containing class then have to maintain a reference to that location? (in which case, for primitives of less than 4 bytes, each instance of the class would actually be larger than if it simply included the primitive directly as it would in the non-static case)
3) Are compilers now smart enough to determine that in cases such as the one above, the variable is 'effectively static' since it would be impossible to have different instances contain different values and therefore optimize it similarly to a final static one?
1) How are final static primitives stored? Are they simply compiled directly into the expressions in which they're used?
Not compiled directly into the expressions. They are compiled into the .class file and referenced by the opcode ldc.
2) If they are actually allocated storage, does each instance of the containing class then have to maintain a reference to that location? (in which case, for primitives of less than 4 bytes, each instance of the class would actually be larger than if it simply included the primitive directly as it would in the non-static case)
No, the "reference" is baked into the bytecode, so nothing needs to be stored on a per-instance basis.
3) Are compilers now smart enough to determine that in cases such as the one above, the variable is 'effectively static' since it would be impossible to have different instances contain different values and therefore optimize it similarly to a final static one?
Not sure, but I doubt it's optimized at the compiler level. The JIT would probably come into play. However, I'm not at all sure what sort of "performance differences" you are expecting. No matter what the case, the performance impact will be negligible. (static/non-static/final/non-final)

Categories