50

If my application has too many static variables or methods, then as per definition they will be stored in heap. Please correct me if I am wrong

1) Will these variables be on heap until application is closed?
2) Will they be available for GC at any time? If not can I say it is a memory leak?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
harshit
  • 7,925
  • 23
  • 70
  • 97

5 Answers5

94

Static methods are just methods, they are not stored on the heap, they just don't get to use a "this" parameter.

Static variables serve as "roots" to the GC. As a result, unless you explicitly set them to null, they will live as long as the program lives, and so is everything reachable from them.

A situation is only considered a memory leak if you intend for the memory to become free and it doesn't become free. If you intend for your static variable to contain a reference to an object for part of the time, and you forget to set it to null when you're done with that object, you would likely end up with a leak. However, if you put it in the static variable and intend for it to be there for as long as the program is running, then it is most definitely not a leak, it is more likely a "permanent singleton". If the object got reclaimed while you wanted it to still exist, that would have been very bad.

As for your question about the heap: All objects in Java exist either on the heap or on the stack. Objects are created on the heap with the new operator. A reference is then attached to them. If the reference becomes null or falls out of scope (e.g., end of block), the GC realizes that there is no way to reach that object ever again and reclaims it. If your reference is in a static variable, it never falls out of scope but you can still set it to null or to another object.

Uri
  • 88,451
  • 51
  • 221
  • 321
  • IIRC the static fields will be GCed as soon as the class that declare them is GCed. If th elast instance of the class is gone the class declaration will go and the static fields with it. – ordnungswidrig Mar 13 '09 at 14:26
  • 1
    I'm not sure if @o11rig is completely accurate, but I believe that the GC is allowed to collect statics for classes that have no members under certain circumstances. I've heard this from a couple sources, but never heard an exact explanation. – Bill K Mar 13 '09 at 16:30
  • Slight quibble: All Java *objects* live in the heap. Object *references* and primitives can be stored on the stack if they are locals of the currently executing method, and are stored on the heap otherwise. (Except for in any modern JVM with a JIT, where the JIT's optimizer may put objects wherever it likes, as long as it still *acts* like the objects are on the heap.) And it could be argued that static methods -- or, at least, the Java bytecode that implements them -- lives on the heap as well, as part of the Class object that represents the class where they were defined. – Daniel Pryden Jun 25 '11 at 05:03
3

If you have a static hashmap and you add data to it... the data will never disappear and you have a leak - in case you do not need the data anymore. If you need the data, it is not a leak, but a huge pile of memory hanging around.

ReneS
  • 3,535
  • 2
  • 26
  • 35
  • Assume static hashmap has lots of objects; and i made the reference of the map to null (not all the objects it contains)? is it a memory leak? since you have stated that "the class loader permanently holds a static reference and therefore the GC will never kick in" ? – Kanagavelu Sugumar Apr 24 '13 at 19:02
  • If you set the static reference to null and you have not referenced that map anywhere else, the memory will be freed. The referenced objects in that mapped will be freed as well if they are not referenced by someone else. – ReneS Mar 07 '15 at 13:14
2

Objects directly or indirectly referenced by statics will remain on the heap until the appropriate class loader can be collected. There are cases (ThreadLocal, for instance) where other objects indirectly reference the class loader causing it to remain uncollected.

If you have a static List, say, and add references to it dynamically, then you can very easily end up with "object lifetime contention issues". Avoid mutable statics for many reasons.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • does this use of static in class member look like possible leak?: private static final Function r = (status) -> {return new Object();}; – Ajeetkumar Nov 19 '21 at 08:54
  • @Ajeetkumar No. That's an immutable field. All it is referencing is `Function`, `String`, `Object` and the class itself (via a method reference). – Tom Hawtin - tackline Nov 20 '21 at 13:45
1

As long as you can reference these variables from somewhere in the code it can't by GCed which means that they will be there until the end of the application.

Can you call it a memory leak, I wouldn't call it a memory leak, usually a memory leak is memory that you normally expect to recover but you never do, or you only recover part of it. Also memory leaks usually get worse in time (eg: every time you call a method more memory is "leaked") however in this case the memory usage for those variables is (kind of) static.

hhafez
  • 38,949
  • 39
  • 113
  • 143
  • There is no need for static variables to be referenced from your code... the class loader permanently holds a reference and therefore the GC will never kick in. – ReneS Mar 19 '09 at 02:37
1

It won't cause a memory leak in the classic C sense... For example

Class A{

static B foo;

...

static void makeFoo(){
   foo = new B();
   foo = new B();
}

In this case, a call to makeFoo() won't result in a memory leak, as the first instance can be garbage collected.

patros
  • 7,719
  • 3
  • 28
  • 37