I have some objects that are created/destroyed very often and that can exist in many lists at the same time. To ensure I have no references left to them the objects have a flag isDestroyed, and if this is set, each list is responsible for removing the object from the list.
However this is ofcourse a growing ground for memory leaks. What if I forget to remove objects from one of the lists? To visually monitor that the program behaves correctly, I override finalize and increase a global variable to track destructions (not a formal test, only to get an idea). However as I have no control over the GC, I could in theory wait forever until something is destroyed.
So the question is two-fold: When having objects that are in multiple lists, is a "isDestroyed" considered a good way to control the object lifetime? It forces everyone who uses the object to take care to remove it from their lists, which seems bad.
And, is there any good way to see when the reference count reaches zero on an object, ie when its scheduled for destruction?
EDIT: To be more specific, in my case I my objects represent physical entities in a room. And I have one manager class that draws each object, therefore it is in one list. Another list contains all the objects that are clickable, so there I have another list. Having all objects in one list and using polymorphism or instance of is not an option in this case. When a object is "destroyed", it should neither be shown or clickable in any way, therefore I want to remove it from both lists.
You should have a look at the java.lang.ref Package.
And, is there any good way to see when the reference count reaches
zero on an object, ie when its scheduled for destruction?
You can use the ReferenceQueue Object
From JavaDoc of java.lang.ref.ReferenceQueue
Reference queues, to which registered reference objects are appended
by the garbage collector after the appropriate reachability changes
are detected.
I think this what WeakReference and ReferenceQueue is for - you create a WeakReference for the object you are tracking and associate it with a ReferenceQueue. Then you have another thread that processes WeakReference(s) as it is returned from ReferenceQueue.remove(). WeakReference's are added to ReferenceQueue when the referenced objects is GC'd. But can you give an example on what these lists you are trying to clean up when the referenced objects are dead?
The way this is usually handled is through the Observer pattern. Each list attaches a destroy-listener that gets notified upon destruction. How this meshes with you architecture, I have no details to judge from.
If you want to be notified I'm almost sure you need PhantomReference, read here:
http://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Related
Suppose I have an ArrayList<Foo>. This list is being modified very frequently. Even the values of the elements in the list will have values that change all the time. All of the modifications to this list are being performed by the main thread.
How would I go about cloning the list (deep level, elements should be cloned also) in a separate thread in such a way that it does not delay the main thread (or at least not by much), and the copied list contains a snapshot in time (I think the term is atomically) of all of the Foo objects, with there values identical to the original list (again in one snapshot of time).
Thanks in advance. I know the solution has to do with synchronization but I am at a loss in meeting all of the above criteria.
There isn't a simple answer to this unfortunately. If the modifications being made to the list are already threadsafe, you can grab a lock on the list (or whatever you're using for synchronization), make your copy, and release the lock. You'll need to make sure that any modifications to the items themselves are using the same lock.
Alternatively, you could use immutable constructs (but you need to use this not just for the list, but for the list contents as well), then you'll never need to lock and can just grab a copy of the list at your leisure.
There are downsides and risks to both approaches. If you want a good resource, I strongly recommend Java Concurrency in Practice.
In this amazing book the author Josh Bloch mentions:
"Oh, and one more thing: there is a severe performance penalty for using finalizers. On my machine, the time to create and destroy a simple object is about 5.6 ns. Adding a finalizer increases the time to 2,400 ns. In other words, it is about 430 times slower to create and destroy objects with finalizers."
Is there a way we can delete and object in java?
I thought we can simply let the objects fall out of scope or reset them to null. I intend to experiment this on my machine, seems like a fun idea but I am not sure how to delete and object.
Once you make the reference variable refers to null (assuming last reference) and that variable gets out of its scope, then the object is eligible to be garbage-collected at next garbage-collection cycle.
An object will cease to exist when there are no longer any strong rooted references to it; in most cases that's exactly what should happen. In some cases, however, an object will ask an outside entity to do something on its behalf, possibly to the detriment of other entities, in exchange for a promise to let that other entity know when its services are no longer required. For example, a "File" object might ask the OS for exclusive access to a file; until the OS is told that such access is no longer required, it will block everyone else's ability to use that file.
If an object which had made such a promise were abandoned and simply ceased to exist, the outside entity would keep on doing whatever it had been asked to do, to the detriment of everyone else, even though its actions were no longer of any benefit to anyone. To avoid this situation, Java allows objects to request notification when the GC notices that they seem to have been abandoned. Such notifications will be given (i.e. Finalize will be called on such objects) before the objects cease to exist, but there's no real guarantee of timeliness beyond that. An object which is finalized can then notify any and all entities acting on its behalf that they should stop doing so.
The creators of Java may have expected finalizers to be the primary mechanism by which objects could notify outside entities that their services are no longer required, but finalization really doesn't work very well. Other mechanisms such as AutoCloseable or PhantomReference are better in many cases.
this question is for either android or java .
suppose i have an instance of a class (even a thread) .
i wish that in order to make it fool proof against forgetting to dispose/close the instance (and avoid any possible memory leaks) , if there are no more references to this instance , it will automatically call a specific method , disposing/closing itself (in case of a thread , it will probably interrupt itself) .
is it possible to enforce such a thing?
if needed , i don't mind that such a thing will occur only during GC .
if there are no more references to this instance , it will
automatically call a specific method , disposing/closing itself (in
case of a thread , it will probably interrupt itself)
finalize() does what you describe here. You very rarely see it used though, and there are some pitfalls when using it. As you cant control garbage collection, you cant be sure when finalize will be run, if ever! From the api:
the usual purpose of finalize, however, is to perform cleanup actions
before the object is irrevocably discarded. For example, the finalize
method for an object that represents an input/output connection might
perform explicit I/O transactions to break the connection before the
object is permanently discarded.
You cant enforce garbage collection. You can only suggest the JVM to do so using System.gc(), but it is not guaranteed that it will be done.
I know this is very late but I hope it might help someone someday.
You can receive such events this by using the using the library that i am developing called gcRadar. It provides events when an object is orphaned and after the actual garbage collection of the object.
Any suggestions for improvements in the library are welcome.
There is no way to access the references held by the VM. As Zavior suggested, the only way to know for sure that an object, or an "island" of objects is inaccessible, is to use the finalize method.
Please note that you will only get notified during GC runs. So it does not really help closing/disposing resources that are still referenced but should be closed. If you want to do that as well and do not want to use such constructs as try/catch/finally, you should write a manager class for the resources.
With any of the possibillities, including a manager class, you will not get a "bulletproof" way to consolidate your resources. Being careful is the best solution IMHO.
EDIT:
I have found this thread that may be useful.
I would like to implement a ORM-style system that can save updates to POJOs when they are no longer reachable by the caller.
I thought the reference classes could do it, but they seem to only enqueue the reference after the object has been cleared (I was hoping it was when they were able to be collected), so once enqueued the .get() method will always return null.
I could use a finalizer but last time I checked those were questionable (Not guaranteed to run promptly or run at all)--I believe a combination of finalizers and runShutdownHook() would work but that's getting into fairly swampy territory.
Is there another path I'm not thinking besides the obligatory "Just have the caller call .save() when he's done"?
Are you just trying to avoid having to call save() on every POJO that you modify?
This can be done reliably using a persistence session object, like this:
Open a new session object.
Load objects via the session object. The session object maintains references to all the objects it loads.
Make any changes to the loaded objects. It is not necessary to call a save method on updated objects.
Close the session object. The session saves all of its objects. It might even be fancy enough to keep a copy of clean loaded data, compare all of its objects to the clean data, and save only the ones that have been modified.
And if you don't want to pass session objects through your code, you can take things a step further with the Unit of Work pattern, associating a session object to the current thread:
Start a unit of work. This creates a session object behind the scenes and associates it with the current thread.
Load objects. Whenever an object is loaded, your ORM automatically associates it with a session object based on the current thread.
Make any changes to the loaded objects. It is not necessary to call a save method on updated objects.
Complete the unit of work. This closes the session object, saving all the objects.
This fixes several problems with a reachability based solution:
You are not relying on nondeterministic garbage collections, which may have a long time between runs, or not run at all.
All objects modified in one operation are saved together. If you rely on reachability, different objects modified in the same operation can become unreachable at different times, meaning your modifications can be saved to the database in bits-and-pieces.
Rollback is much easier - just give your session object a rollback() method. With a reachability solution, you would need to remember to call rollback() on every modified POJO if an operation fails, which is really the same as your original problem.
Perhaps see http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html or research the Unit of Work pattern and emulate some of those ideas.
Use the Observer Pattern do build a ClearanceManager and some Destroyables.
IDestroyable is an interface, which is used for the observers it contains the method public void destroy()
The ClearanceManager is the Subject of the Observerpattern. Maybe use Singleton here to ensure you have just one ClearanceManager object in your application.
Use a Set internaly inside the ClearanceManager (not a List to ensure Objects can just be added once)
support an addDestroyable(IDestroyable destoryable) method (and maybe a removeDestroyable one).
During Runtime the Classes for which you need some destructor emulation, can register them self at the ClearenceManager. ClearenceManager.getInstance().addDestroyable(this);
The ClearanceManager has an doClearance() method, which should just be called at the end of the Main method. It iterates threw the private Set and calls destroy() on every IDestroyable object.
Doing it this way you can emulate destructors, without using them, because using destructors you are losing control about the existance of myabe needed object.
You do not know when overwriting finalize, when it is called.
Maybe, if you do not want to call doClearance() in your Main method you can use here, but just here, a real destructor finalize(). Because there are references in the ClearenceManager to the needed Objects, they will not be destroyed first. But maybe mhh, if there are cross references .... better do not use finalize, use doClearance() and have fun with it :)
I think you are barking up the wrong tree here.
All of Java's finalizer and Reference mechanisms based on reachability depend on the garbage collector to determine whether the respective objects are reachable. So if you use any of the Reference mechanisms for some kind of finalization, you run into much the same issues that make finalize a bad idea.
It is technically possible to implement your own mechanisms for doing reachability; e.g. by implementing your own application-specific reference counting. However, it is likely to be expensive, fragile, and make your code look horrible. (Reference counting in Java is likely to be messier and more fragile than in C++, because you can't overload reference assignment operators to ensure that reference counts are adjusted transparently. So every reference assignment needs to be wrapped in a method call.) So I'd say that doing your own reachability analysis is a bad idea.
So, to be practical you need to either:
rethink your design so that you don't do things based on reachability, or
live with the consequences of using finalize.
The first option is clearly the best, IMO.
maybe you can subclass PhantomReference, and store necessary data in it for final actions.
Is there a way to create register a handler that will be called exactly at the time when the last reference to a certain object is released?
An example would be an object that is backed by a physical data file and once the object become unreferenced, the file should be closed and than renamed. It would be nice if this was possible without having to explicitly call a "close" method on that object.
All the notification mechanisms I am aware of from the Weak/Phantom reference area only state that notification will occur at some point in time but there is no gurantee as to when this will happen...
In short, no.
The Java specification explicitly denies you the ability to know when the last reference is released. JVM implementations (and optimizations) depend on this. There is no hook.
From my understanding, and I've looked for some time to find a "destructor" for java objects, there is no way to know when you lose the last reference. Java tracks references to objects but for performance reasons, updates this information only during garbage collection.
The closest thing is the finalize method which should be called during garbage collection but there's no guarantee that it will be called even then.
I think WeakReference does what you want. A WeakReference gets put into the ReferenceQueue as soon as its weakly reachable (i.e. all strong references are gone).
See this article by Ethan Nicholas.
If you are worried about some references not reaching the ReferenceQueue at shutdown, then keep a list of all objects created (using WeakReferences or PhantomReferences). Add a shutdown hook that checks the list for any outstanding references and perform whatever action you need.
Problem is, "How do you implement this, without something holding a reference to the object?"
Even if you could get passed that problem, say with a service we'll call the HandleManager, the HandleManager would then have to create a new reference to the object, to pass to your handler. Then, your handler could either (a) store a reference to it, which would confuse the HandleManager which was expecting to destroy the unreferenced object; or (b) release the reference, which means that the final reference was once again released, which means the Handler has to be called again....
If you need to manage external resources like files, the best you can do in java is a close() function (whatever name you choose). You can use finalize() as a "belt and suspenders" insurance policy, but that has unpredictable timing. So your main line of defense needs to be the close() function.
See my answer Why would you ever implement finalize()?
This cannot be done with Java -- it needs a reference-counting garbage collector as far as I can tell. Have you considered opening and closing your object's physical data file as needed, rather than keeping it open for the lifetime of the object?
You could override finalize() in your object, but that is problematic for reasons others have mentioned.
For your specific example, you could take a look at using something like File.deleteOnExit(), which would remove the file once the VM exits.