views:

378

answers:

7

Is this statement true, false, or poorly formulated:

"In Java, memory leaks must always be related somehow to a long-lived object."

In this context, I am referring simply to regular objects, and not to system resources in general (file descriptors, and so on).

An example of a long-lived object might be a singleton (as typically implemented, at any rate), which lives for as long as an application is running.

+9  A: 

Misleading.

While the statement is technically true, the memory leak is caused by objects that live longer than expected.

Pyrolistical
+1 for the succinct answer. Technically true for a perverse understanding of 'technical', in the sense of pure logical.
gimpf
The key word in the question is "related". The question is not whether the long-lived object is the CAUSE of the leak, but whether it is RELATED to the leak's existence somehow or other. Different idea.
John O
+2  A: 

The statement is correct but poorly formulated IMHO. Memory leaks arise as a result of objects still being referenced after they are no longer needed.

The only other cause of memory leaks I can think of is a Java application failing to free resources in a JNI native library.

Interesting article here.

Adamski
A: 

Depending on the specifica of long-lived, and the inclusion/exclusion of JRE bugs, and the meaning of memory-leak (what's about memory-leaks for just half of the application livetime?), and some garbage collector special cases (for which G1 shall improve the situation) etc. etc....

Well, the question without further context is poorly formulated, but, contrary to Pyrolistical, I tend to say it is technically false, as for any practical definition of memory leak I see no relation to such long-live objects as you describe them.

Of course, one can say without some reference on the stack, which ultimately depends on main's execution time, or some other root reference somewhere, nothing exists; but with such a semantics, the question becomes meaningless. It would be like saying without a computer I cannot run Java applications. Hooray, won the 0$ price.

gimpf
A: 

Since the only time Java really allocates memory is when it's creating objects (well, objects & arrays, but same diff), that's absolutely true but not very useful.

It would be more useful to say WHY the objects are long-lived.

If you are writing a paper or something, I'd describe the "Roots" of the object tree that cause objects to be retained.

These include:

  • Temporary variables on the stack (of any thread)
  • Static variables (from any class)
  • Special references from JNI native code

I believe there are more, the doc I copied this from felt old. I know RMI can hold references that are not reclaimed (might fall under that "JNI" bullet I guess)

Bill K
A: 

First some things to establish:

  • Objects are referenced from other objects, and the entirety of a running program can be visualized as a graph of objects referencing other objects.
  • By definition, objects can be garbage-collected if they cannot be accessed by a live thread.
  • It's possible to create an application, either purposely or by accident, which repeatedly creates objects and then never lets those objects be garbage collected. Do that repeatedly enough in a long-running program and you'll have a noticeable memory leak.

You may have different values for "long-running", "noticeable", and "repeatedly", but the idea is that memory leaks are the last point. Thus, if you say that memory leaks are associated with a long-lived object, then I say that's misleading - objects take up memory, so of course they are associated with an object of some kind, but the cause is in the application design, not the object reference hierarchies or the garbage collector behaviors.

Actually, to say that memory leaks are always associated with a "regular" long-lived object - I'd say false. But still misleading, as per above.

weiji
+2  A: 

"In Java, memory leaks must always be related somehow to a long-lived object."

A long-lived object is a Singleton, or something that will live as long as the application is running.

We can turn the statement around a bit and phrase it in the form of a question. You can ask:

Is it possible to have memory leaks in a Java application that are not related to a Singleton or other core component (that is long-lived by design)?

As we know, and many here have pointed out, memory leaks in the context of Java are essentially objects to which there are inadvertant strong references remaining, rendering them unavailable to the garbage collector.

In order to answer our new question, we would need to imagine a scenario in which we have a pair of objects that would normally be garbage collected after they move out of scope, but have created a circular reference (two or more objects that have strong references to each other). Here there would be strong references to these objects, and as they have both gone out of scope, they are no longer tied to any 'long-lived' objects. Would they be considered leaks?

To answer this, kdgregory has posted in his blog an article entitled "Java Reference Objects or 'How I Learned to Stop Worrying and Love OutOfMemoryError'":

You may be wondering what happens if you have a circular reference: object A contains a reference to object B, which contains a reference back to A. The answer is that a mark-sweep collector isn't fooled: if neither A nor B can be reached by a chain of strong references, then they're eligible for collection.

akf
+1  A: 

Memory leaks can also be caused by short-lived Java objects that allocate memory outside of the Java memory model and don't release it. This memory won't be leaked by the Java process, but it could still cause you to run out of system resources.

So make sure to check what other processes/programs are being invoked by your Java program as well.

Larry Watanabe