neshone
neshone

Reputation: 134

In which cases is finalize() actually USED?

I've found multiple posts stating when finalize() should NOT be used and that it shouldn't be used in general because nobody guarantees the the object will be garbage collected during the lifetime of the application (unless you actually need the object throughout the lifetime of the application, this is a memory leak in my book). But let's say I have a Java class that initializes something (does memory allocation and initialization) in native space through JNI. As far as I'm concerned, there two ways I can implement this:
1. Implement an init() and deinit() method in the class to do the native initialization and deinitialization. This has a down side that I have to take care of the object life cycle and can't leave that to the garbage collector (which is not very Java-like).
2. Do the initialization in the constructor and deinitialization in the finalize() method. This basically enables the objects to be automatically garbage collected like with any other Java class.

What I'm asking is - is there a reason for me not to go with number 2?

Thanks,
Nenad

Upvotes: 0

Views: 113

Answers (2)

user3054142
user3054142

Reputation: 66

Code execution doesn't necessarily release resources when the latter should be released. Therefore, I would use finalize as soon as you know that resources are no longer needed if these resources are significant. If resources are small don't use finalize because it comes with an overhead.

Upvotes: 0

Stephen C
Stephen C

Reputation: 718826

What I'm asking is - is there a reason for me not to go with number 2?

Well one reason would be that the native resource won't be release until the GC has reclaimed the Java object whose finalize method will reclaim it.

Whether this reason is actually relevant depends on the nature of the native resource.


Really, when you think about it, this is the same debate that the Java designers would have had about closing streams.

  • They could have not provided a close() method, and left it entirely to a finalize method ... except that that would lead to problems with output stream not being flushed soon enough, and running out of "file descriptors".

  • They could have left it entirely to the close() method ... except that if you did forget to close() a file (and there wasn't a finalize method) you would leak file descriptors ... permanently.

  • Instead, they implemented both close() and finalize, and they implemented the latter to call the former. Thus you get the advantage of closing when the program says so, and something to clean up1 if it neglects to call close().

1 - Of course, there can be problems if you rely on the stream finalize method for cleanup; e.g. if the stream remains reachable by accident, or if it doesn't get garbage collected soon enough, and you run out of file descriptors anyway. And non-deterministic flushing out output could be a problem too.


OK. What about when the resource in question is purely memory? Isn't that the same as garbage collecting then?

I don't see that. True garbage collection doesn't rely on you implementing a finalize method, or a close method, or something else that explictly releases stuff.

Upvotes: 2

Related Questions