How to tell when a Java object's memory is released? - java

I have a Swing browser application with a bug that as I add/remove to/from the GUI the memory isn't released for those objects and I'm trying to track down what is holding onto them. Problem is I don't know how to tell when something has actually be fully released from memory.
Is there a way to tell if an object has been released from memory? I'm used to Objective-C where there are several ways to tell.
Thanks

You can't really do it in Java. All the answers mentioning finalizers are really not what you're after.
The best you can do is enqueue a PhantomReference in a ReferenceQueue and poll until you get the reference.
final ReferenceQueue rq = new ReferenceQueue();
final PhantomReference phantom = new PhantomReference( referenceToObjectYouWantToTrack, rq );
You want to read Peter Kofler's answer here (it explains what a PhantomReference is):
Have you ever used Phantom reference in any project?
Very interesting read here:
http://www.kdgregory.com/index.php?page=java.refobj
Basically, I'm using a PhantomReference in a project where a very special kind of cache needs to be computed once, when the software is installed. To efficiently compute this (disk-based) cache, a gigantic amount of memory is needed (the more the better). I'm using a PhantomReference to track "nearly exactly" when that gigantic amount of memory is released.

There are multiple ways of detecting memory leaks. Here the three I'm currently thinking of:
Attaching a Profiler to your application (Netbeans or Eclipse TPTP should be useful here)
Making a heap dump and analyze (with Eclipse Memory Analyzer) what instances of a class are held in memory by which other instances.
Attaching VisualVM to track Garbage Collection status.

Edit:
As NoozNooz42 has pointed out, a PhantomReference can do everything a finalizer can, without the problems finalizers present. So, I encourage using PhantomReferences over extending finalize(). I am keeping my original post in tact, since I think Java programmers should at least know that finalize() exists.
Original Post:
Every Java class has a finalize() method that gets run when no other Objects hold a reference to that class. You can extend this method like so:
protected void finalize() throws Throwable {
try {
// Do whatever you want
} finally {
super.finalize();
}
}
By doing so, you can figure out if anything holds a reference to the Objects in question. Just make sure you always call super.finalize() if you use this approach.
Reference on finalization:
http://java.sun.com/developer/technicalArticles/javase/finalization/

Try YourKit. It's a Java profiler which can show you your memory usage and what the heck is going on. IIRC, the free trial can integrate with Eclipse and has all of the paid version's features (it just has a time limit).

Related

what to use instead of finalize() in java

Let's consider following code:
class Table {
private static int number_of_Tables=0;
public Table(){
++number_of_Tables;
}
public void finalize(){
--number_of_Tables;
}
public static int current_TableCount(){
return number_of_Tables;
}
}
What I want to achieve is that when Garbage Collector (GC) destroys the Object that the count of available Objects gets decreased by one.
But everyone here on topic of finalize() is saying that using this method is very bad because following could happen: even though there are no references pointing to the object the GC may not destroy it immediately because GC doesn't work around the clock i.e GC will be invoked after certain amount of object are there to be destroyed i.e at certain times GC will perform the cleanup, which means that even though the object is not available anymore my counter wouldn't decrease and I would give the false information upon invoking the method curret_TableCount()
What do people do instead, to solve this kind of a problem with certainty?
There must be some kind of solution in Java?
EDIT: I need to recognize when the object is not referenced anymore i.e during runtime there exists not even one pointer(reference) to the object when this is true, i would then decrese the number of that kind of objects by one.
…following could happen: even though there are no references pointing to the object the GC may not destroy it immediately because GC doesn't work around the clock
That’s correct. The garbage collector’s purpose is to manage memory and only to manage memory. As long as there are no memory needs, the garbage collector doesn’t need to run. It’s perfectly possible that an application runs completely without any gc cycle, when there is sufficient memory.
Further, there is no guaranty that a garbage collector run identifies all unreachable objects. It might stop its work when it identified enough reclaimable memory to allow the application to proceed.
This, however, is not the only issue. Often overlooked, the fact that the garbage collector only cares for memory needs, implies that an object may get collected even when being in use, when its memory is not needed anymore, which is possible with optimized code. This is not a theoretical issue. See for example this bug or that bug related to naive dependency on finalization, even in JDK code.
Note that even if finalize() happens to get invoked at the right time, it’s invoked by an unspecified thread, which requires using thread safe constructs.
What do people do instead, to solve this kind of a problem with certainty?
People usually don’t have that kind of problem. If you truly manage a non-memory resource, you should use an explicit cleanup action, i.e. a method like dispose() or close(), to be invoked after use. The straight-forward approach is to let the class implement AutoClosable (or a subtype of it) and use the try-with-resources statement.
Cleanup actions triggered by the garbage collector are only a last resort for dealing with scenarios where the explicit cleanup has been forgotten. As explained, implementing them needs special care.
In case of a counter maintained only for statistics, you may simply live with the fact that it is imprecise. Normally, you don’t need to know how many instances of a class exist. If you really need it, e.g. when trying to debug a memory leak, you can take a heap dump, a snapshot of all existing objects, and use a dedicated analysis tool.

How does the GC know when to collect an object?

I know that the GC collects objects that have no references pointing to the object in question, but what happens in the event of listener objects?
Suppose you have an AnimationDelegate that listens to data from a DataSupplier. When the DataSupplier recieves data and fires off the event to the AnimationDelegate, the delegate will then invalidate (/update/redraw etc...) a Graphic. Now say the screen is disabled, removed or, through various means, the graphic can no longer draw and is collected. The AnimationDelegate is still registered to the DataSupplier. How will the GC know to collect it? Should one unregister the delegate in the graphics finalize() method?
I'm afraid the answer won't fit the format :) Start with this article by Brian Goetz: he's a perfect person to read if you're interested in GC.
Basically, as soon as object is not reachable from active threads, it's collected. The actual algorithms vary even within one JVM, but the point stays the same: what's not reachable is a garbage. What's reachable is not a garbage. Easy.
GC will not collect the Graphic in your example, as it's reachable from AnimationDelegate, which in turn is reachable (via subscription) from DataSupplier which is supposed to be reachable from some active thread. So the answer will be: your assumptions are wrong; GC will not collect anything here.
To answer your question, unsubscribe everything you don't need.
As #rfeak rightfully says, finalize() is a big no-no. It's almost impossible to use it properly, and it's way too easy to use it wrong. That said,it's OK to use it as a backup solution when you need to free resources. But generally your application has to be able to work just fine even if finalize() never gets called.
It all depends on the JVM you're using and the GC. Most default GC from the JDK use the so called "tracing collectors", which simply start at a given root set of objects and trace all the objects reachable from that set. All the other objects in memory are seen as garbage and deleted. So circular references aren't really a problem unless one of the objects is reachable from the root set.
What is the root set of objects? Well if memory serves right roots can be found in: program registers, local variables in each thread's stack and static variables.
To see if your objects will be GC'd we would know more about the design of your application.
#Edit: Oh and I almost forgot: Memory Management in the JavaHotSpot™ Virtual Machine. This is a pretty good overview of how it all works.
It will only know if you have removed the references (nulled them out).
However, don't do this on finalize(). Finalize is bad bad bad. There should be other lifecycle methods available for cleaning up listener(observer) type objects.
By the way, observer pattern is notorious for creating memory leaks because the GC couldn't collect due to lingering references.

Java Memory Leaks

I'm creating a service that will run constantly, each day at a specified time it will run the main body of the program.
Essentially:
while(true){
run();
Thread.sleep(day);
}
After a while, I'm getting OutOfMemoryHeapExceptions.
After reading about this a little I'm thinking its because any objects created inside the run() method will never be garbage collected.
Therefore I have done something like:
public void run(){
Object a = new Object();
a.doSomething();
a= null; //Wasn't here before
}
My question is, will this solve my problem? I'm under the impression that once an object is null, the object it previously referenced will be garbage collected? Also is this a good idea? Or should I look at doing something else?
Thanks
Adding a = null will almost certainly be insufficient to fix the problem (since a is about to go out of scope anyway).
My advice would be to use a memory profiler to pinpoint what's leaking and where.
I personally use YourKit. It's very good, but costs money (you can get a free evaluation).
Another recently-released tool is Plumbr. I am yet to try it, but the blurb says:
Try out our Java agent for timely discovery of memory leaks. We'll tell you what is leaking, where the leak originates from and where the leaked objects currently reside - well before the OutOfMemoryError!
That might indeed help, in some circumstances the GC algorithm needs a little help to perform, but it doesn't guarantee to solve your problems, merely delay them.
My advice:
Simulate the same behavior with a lower time period, so you can force the error to happen.
Run it with a profiler and see where all that memory is going, and work from there.
Your impression is incorrect. Objects created inside the run() method will be garbage collected provided they 1) go out of scope, and 2)have released any native or remote system resources they are using.
What functionality are you actually performing inside your run() method call? Are you reading files, making database calls, writing to sockets? Without knowing the details its very difficult to provide a better suggestion.
No. You don't need to set the variable to null. The VM knows that you exit that scope and that the variable a no longer exists, so it automatically decrements the reference count and your object is elegible for garbage collection if it had no other references.
The error is somewhere else.
Setting references to null depends if your object is still in scope in a long time consuming process, though theoretically it will mark the reference as null you cannot guarantee when it will be garbage collected.
You need to check if your objects are being held in long scope somewhere in your code.
Found a nice explanation of setting references to null : Does setting Java objects to null do anything anymore?
In order to corner out your issue you need to profile your application.
Searching SO gave so many pointers on Garbage Collection that I have decided to just place the search string here:
https://stackoverflow.com/search?q=Java+Garbage+collection+and+setting+references+to+null
http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html
Local variables should be collected by GC. So, you don't need to put obj=null;. Because Object is also stored in Heap area.
You should get a memory dump and analyze that using tools like JConsole JVisualVM.
The scope of the run() method is left before the Thread.sleep(day); and thus any variables inside that method are destroyed. After that a won't exist any more and thus the object referenced by that variable might be eligible for garbage collection provided there's no other reference to it.
Analyzing a memory dump should allow you to find any references to those object if they still exist.
It might as well not be those objects but others that are kept alive and which eat up the memory. That depends on what you're actually doing and might be hard to analyze here. Thus look out for huge object graphs in terms of memory usage.
For instance, we had a problem with database connections that were created frequently (XA recovery mechanism) and we thought they'd be destroyed once the method scope is left. However, the server put those connections into a static list and never cleared it and thus we ended up with no memory really soon. What helped us identify that case was analyzing a memory dump. :)
In the short term a pragmatic approach to keeping your application stable is to exit the JVM after each execution. Use a batch scheduler (e.g. cron on *nix, at on Windows) to execute your application just once every day. Any memory leaks will be cleaned up when the JVM exists for sure. However you may have to be careful you're not leaving database connections open, etc.
This will give you time to troubleshoot and fix the underlying memory leak issues while keeping your production code running and not requiring support staff to restart servers, etc.
I'm assuming you're not running out of memory on a single execution

Why does Java not have any destructor like C++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Java has its own garbage collection implementation so it does not require any destructor like C++ . This makes Java developer lazy in implementing memory management.
Still we can have destructor along with garbage collector where developer can free resources and which can save garbage collector's work. This might improves the performance of application. Why does Java not provide any destructor kind of mechanism?
Developer does not have control over GC but he/she can control or create object. Then why not give them ability to destruct the objects?
You're asserting that "garbage collection is very expensive" - could you back that up with evidence? Garbage collection is certainly not free but modern garbage collectors are very good.
Note that one of the ways in which the GC is able to be efficient is that it knows it's the only thing doing memory allocation and deallocation (for managed objects). Allowing a developer to explicitly free an object could hamper that efficiency. You'd also need to worry about what would happen if a developer tried to "use" a freed object:
Foo f = new Foo();
Foo g = f;
free(f); // Or whatever
System.out.println(g.toString()); // What should this do?
Are you proposing that each object should have an extra flag for "has this explicitly been freed" which needs to be checked on every dereference? This feels like a recipe for disaster, to be honest.
You're right though - it does allow Java developers to be lazy in this area. That's a good thing. IDEs allow developers to be lazy, too - as do high-level languages, etc. Laziness around memory allocation allows developers in managed environments to spend their energy worrying about business problems rather than memory management.
Garbage Collection is very expensive.
In fact, for complex applications, the performance of garbage collection is competitive with manual storage management based on malloc / free. There is a classic paper by Benjamin Zorn that clearly demonstrates this. In this paper, Zorn describes how he modified some large heap intensive applications to use a conservative garbage collector instead of malloc and free. Then he benchmarked the original and modified versions of the applications. The result was comparable performance.
This paper was published in Software Practice and Experience in 1993. If you haven't read it, you are not qualified to make pronouncements on the "inefficiency" of garbage collection.
Note that this research was done with a 1993-vintage conservative garbage collector. A conservative collector is mark-sweep without any compaction; i.e. non-garbage objects don't move. The latter means that allocation of space for new objects is as slow and complicated as malloc. By contrast, modern garbage collectors (e.g. Java 6/7 ones) are generational copying collectors which are much more efficient. And since copying compacts the remaining non-garbage objects, allocation is much faster. This makes GC even more competitive ... if one could find a way to do the comparison.
Developer does not have control over GC but he/she can control or create object. Then why not give them ability to destruct the objects?
It depends on what precisely you mean by "destruct".
In Java, you do have the ability to assign null. In some circumstances this may hasten the destruction of an object.
In Java, you can use finalizers and Reference types to notice that an object is about to be destroyed ... and so something about it.
In Java, you can define a close() (or equivalent) method on any object and have it do something appropriate. Then call it explicitly.
In Java 7, you have the "try with resources" construct for automatically calling close() on the resources on scope exit.
However, you can't cause a Java object to be deleted NOW. The reason this is not allowed is that it would allow a program to create dangling references, which could lead to corruption of the heap and random JVM crashes.
That is NOT the Java way. The philosophy is that writing reliable programs is more important than efficiency. While certain aspects of Java don't follow this (e.g. threading) nobody wants the possibility of random JVM crashes.
The C++ destructor is not a way to destruct objects - it's a set of operation that are to be done when the object is destructed. In Java you have no control on the time when objects are destructed (they may be even never destructed), so putting any important code to be executed at object destruction is strongly discouraged (although possible - finalize method). If you ask not for a destructor but for a way to explicitly destroy given object, you are inviting dangling references into your code. They are not welcome.
This makes Java developer lazy in
implementing memory management.
No, it releases them to perform useful work.
And Garbage Collection is very
expensive.
Compared to what? Facts? Figures? You're about 20 years out of date with that remark. The take-up of Java alone effectively disproves that contention.
This might improves the performance of application.
Or not. Did you have some facts to adduce?
Then why not give them ability to destruct the objects?
Because it's not required?
Destructors are called when the object is destroyed in C++, not to destroy the object. If you want to guarantee cleanup, make the user call a Destroy method or similar.
If you know you don't some big objects anymore just set the references to them to null. This could maybe speed up the garbage collection of these objects.
The C++ destructor is not a way to destruct objects - it's a set of operation that are to be done when the object is destructed.
I think you are confusing terminology. Here is how I see it:
create object = first allocate memory, then construct via constructor
destroy object = first destruct via destructor, then deallocate memory
How the memory is allocated and deallocated depends. If you use new and delete, the memory management is done by void* operator new(size_t) and void operator delete(void*).
A C++ destructor is useful for freeing any resources owned by the object, not only memory. It may be files, sockets, mutexes, semaphores, or any other resource handles. Using a destructor is a smart way of preventing resource leaks. Wrap the resource handling in a C++ class and make a destructor that frees any allocated resources. I don't see any such method in Java. You have to explicitly free the resource, and this can be tricky if there are many possible exit paths.
No, java does not support destructors. All freeing the memory task is done by GARBAGE COLLECTOR.
Java has it's own memory management feature using garbage collector. When you use finalize() the object becomes available for garbage collection and you don't need to explicitly call for the destructor. C# and Java don't want you to worry about destructor as they have feature of garbage collection.
Java is a bytecode language, it has very strong garbage detection. If you were to allow people to define their own destructors it is likely that they might make some mistakes. By automating the process, Java intends to prevent those mistakes.
You do have the ability to control object destruction in Java. It simply uses a different idiom:
Connection conn = null;
try {
conn = ...
// do stuff
} finally {
try { conn.close(); } catch (Exception e) { }
}
You could point out at this point that this isn't object destruction and that you could, for example, pass that object to something else and still have a reference to it. You are right on both counts. It is simply as close as Java (and most managed platforms) get.
But no Java does not, as you say, have a destructor mechanism as in C++. Some people mistake finalizers for this. They are not destructors and it is dangerous to use them as such.
Memory management for a programmer is hard. You can easily leak memory, particularly when doing multithreaded programming (also hard). Experience has shown that the cost of GC, while real and sometimes substantial, is well and truly justified in productivity increases and bug incidences in the vast majority of cases, which is why the vast majority of platforms now are "managed" (meaning they use garbage collection).

Why do you not explicitly call finalize() or start the garbage collector?

After reading this question, I was reminded of when I was taught Java and told never to call finalize() or run the garbage collector because "it's a big black box that you never need to worry about". Can someone boil the reasoning for this down to a few sentences? I'm sure I could read a technical report from Sun on this matter, but I think a nice, short, simple answer would satisfy my curiosity.
The short answer: Java garbage collection is a very finely tuned tool. System.gc() is a sledge-hammer.
Java's heap is divided into different generations, each of which is collected using a different strategy. If you attach a profiler to a healthy app, you'll see that it very rarely has to run the most expensive kinds of collections because most objects are caught by the faster copying collector in the young generation.
Calling System.gc() directly, while technically not guaranteed to do anything, in practice will trigger an expensive, stop-the-world full heap collection. This is almost always the wrong thing to do. You think you're saving resources, but you're actually wasting them for no good reason, forcing Java to recheck all your live objects “just in case”.
If you are having problems with GC pauses during critical moments, you're better off configuring the JVM to use the concurrent mark/sweep collector, which was designed specifically to minimise time spent paused, than trying to take a sledgehammer to the problem and just breaking it further.
The Sun document you were thinking of is here: Java SE 6 HotSpot™ Virtual Machine Garbage Collection Tuning
(Another thing you might not know: implementing a finalize() method on your object makes garbage collection slower. Firstly, it will take two GC runs to collect the object: one to run finalize() and the next to ensure that the object wasn't resurrected during finalization. Secondly, objects with finalize() methods have to be treated as special cases by the GC because they have to be collected individually, they can't just be thrown away in bulk.)
Don't bother with finalizers.
Switch to incremental garbage collection.
If you want to help the garbage collector, null off references to objects you no longer need. Less path to follow= more explicitly garbage.
Don't forget that (non-static) inner class instances keep references to their parent class instance. So an inner class thread keeps a lot more baggage than you might expect.
In a very related vein, if you're using serialization, and you've serialized temporary objects, you're going to need to clear the serialization caches, by calling ObjectOutputStream.reset() or your process will leak memory and eventually die.
Downside is that non-transient objects are going to get re-serialized.
Serializing temporary result objects can be a bit more messy than you might think!
Consider using soft references. If you don't know what soft references are, have a read of the javadoc for java.lang.ref.SoftReference
Steer clear of Phantom references and Weak references unless you really get excitable.
Finally, if you really can't tolerate the GC use Realtime Java.
No, I'm not joking.
The reference implementation is free to download and Peter Dibbles book from SUN is really good reading.
As far as finalizers go:
They are virtually useless. They aren't guaranteed to be called in a timely fashion, or indeed, at all (if the GC never runs, neither will any finalizers). This means you generally shouldn't rely on them.
Finalizers are not guaranteed to be idempotent. The garbage collector takes great care to guarantee that it will never call finalize() more than once on the same object. With well-written objects, it won't matter, but with poorly written objects, calling finalize multiple times can cause problems (e.g. double release of a native resource ... crash).
Every object that has a finalize() method should also provide a close() (or similar) method. This is the function you should be calling. e.g., FileInputStream.close(). There's no reason to be calling finalize() when you have a more appropriate method that is intended to be called by you.
Assuming finalizers are similar to their .NET namesake then you only really need to call these when you have resources such as file handles that can leak. Most of the time your objects don't have these references so they don't need to be called.
It's bad to try to collect the garbage because it's not really your garbage. You have told the VM to allocate some memory when you created objects, and the garbage collector is hiding information about those objects. Internally the GC is performing optimisations on the memory allocations it makes. When you manually try to collect the garbage you have no knowledge about what the GC wants to hold onto and get rid of, you are just forcing it's hand. As a result you mess up internal calculations.
If you knew more about what the GC was holding internally then you might be able to make more informed decisions, but then you've missed the benefits of GC.
The real problem with closing OS handles in finalize is that the finalize are executed in no guaranteed order. But if you have handles to the things that block (think e.g. sockets) potentially your code can get into deadlock situation (not trivial at all).
So I'm for explicitly closing handles in a predictable orderly manner. Basically code for dealing with resources should follow the pattern:
SomeStream s = null;
...
try{
s = openStream();
....
s.io();
...
} finally {
if (s != null) {
s.close();
s = null;
}
}
It gets even more complicated if you write your own classes that work via JNI and open handles. You need to make sure handles are closed (released) and that it will happen only once. Frequently overlooked OS handle in Desktop J2SE is Graphics[2D]. Even BufferedImage.getGrpahics() can potentially return you the handle that points into a video driver (actually holding the resource on GPU). If you won't release it yourself and leave it garbage collector to do the work - you may find strange OutOfMemory and alike situation when you ran out of video card mapped bitmaps but still have plenty of memory. In my experience it happens rather frequently in tight loops working with graphics objects (extracting thumbnails, scaling, sharpening you name it).
Basically GC does not take care of programmers responsibility of correct resource management. It only takes care of memory and nothing else. The Stream.finalize calling close() IMHO would be better implemented throwing exception new RuntimeError("garbage collecting the stream that is still open"). It will save hours and days of debugging and cleaning code after the sloppy amateurs left the ends lose.
Happy coding.
Peace.
The GC does a lot of optimization on when to properly finalize things.
So unless you're familiar with how the GC actually works and how it tags generations, manually calling finalize or start GC'ing will probably hurt performance than help.
Avoid finalizers. There is no guarantee that they will be called in a timely fashion. It could take quite a long time before the Memory Management system (i.e., the garbage collector) decides to collect an object with a finalizer.
Many people use finalizers to do things like close socket connections or delete temporary files. By doing so you make your application behaviour unpredictable and tied to when the JVM is going to GC your object. This can lead to "out of memory" scenarios, not due to the Java Heap being exhausted, but rather due to the system running out of handles for a particular resource.
One other thing to keep in mind is that introducing the calls to System.gc() or such hammers may show good results in your environment, but they won't necessarily translate to other systems. Not everyone runs the same JVM, there are many, SUN, IBM J9, BEA JRockit, Harmony, OpenJDK, etc... This JVM all conform to the JCK (those that have been officially tested that is), but have a lot of freedom when it comes to making things fast. GC is one of those areas that everyone invests in heavily. Using a hammer will often times destroy that effort.

Categories

Resources