Out of curiosity,
Why is the finalize() method's access modifier is made as protected. Why cant it be public? Can someone explain me any specific reason behind this?
Also, I came to know that finalize() method is called only once. If I call it twice in my program internally, what is happening? Will the garbage collector call this again?
private void dummyCall() {
try {
finalize();
finalize();
} catch (Throwable e) {
e.printStackTrace();//NOT REACHES EXCEPTION
}
}
I answer your question with another question:
Why finalize method shouldn't be protected?
In general, you should try to keep things as much private as possible. That's what encapsulation is all about. Otherwise, you could make everything public. finalize can't be private (since derived classes should be able to access it to be able to override it), so it should at least be protected but why give out more access when it's not desirable?
After reading your comment more carefully, I guess I see your main point now. I think your point is since everything derives from java.lang.Object and consequently accesses its protected members, it wouldn't make any difference for it (or any method in java.lang.Object for that matter) to be public as opposed to protected. Personally, I'd count this as a design flaw in Java. This is indeed fixed in C#. The problem is not why finalize is protected. That's OK. The real issue is that you shouldn't be able to call protected methods in the base class through an object reference of the base class type. Eric Lippert has a blog entry discussing why allowing such kind of access to protected members is a bad idea which is further elaborated on Stack Overflow in this question.
Why is the finalize() method's access
modifier is made as protected. Why
cant it be public?
It is not public because it shouldn't be invoked by anyone other than the JVM. However, it must be protected so that it can be overridden by subclasses who need to define behavior for it.
If i call it twice in my program,
internally what is happening?
You can call it all you want, its just a method after all. However, much like public static void main(String [] args), it has special meaning to the JVM
Will the garbage collector call this
again?
Yes
finalize is meant to be called by the gc only and as such does not require public access
finalize is guaranteed to be called only once by the gc, calling it yourself will break this guarantee, as the gc wont know about it.
Any overriding class can make finalize public, which I believe is bad for the above reasons
finalize should not contain much code, as any exception thrown by finalize may kill the finalizer thread of the gc.
Rant against finalize()
Managing native resources or any resource which requires dispose() or close() to be called may cause hard to find bugs as they will only be released when the jvm runs out of memory, you should release resources manually. Finalize should only be used for debugging resource leaks or for cases where managing resources manually is too much work.
finalize will be called in an additional thread of the gc and may cause problems with resource locking and so on.
the reference classes like WeakReference and ReferenceQueue are an alternative (rather complex) way to deal with cleanup and may have the same problems as finalize() for native resources.
Beware of errors in the above statements, I'm a bit tired :-)
Check out this link which discusses it.
Basically, it would make the most sense for it to be private, as it should only be called by the JVM (garbage collector). But in order to allow a subclass to call the parent finalize() method as part of its finalize(), it has to be protected.
(Edit - And just a general caution - use of the finalize() method is generally discouraged as there's no way of ensuring that it will ever be called. Although that doesn't mean that you'll never have occasion to use it - it's just rare.)
The part about finalize() being called only once applies only to the calls from the GC. You can imagine the object as having a hidden flag "finalize() was called by the GC", and the GC checking that flag to know what to do with the object. The flag is not impacted in any way by your own handmade calls to finalize().
On finalization, read this article from Hans Boehm (who is well-known for his work on garbage collection). This is an eye-opener about finalization; in particular, Boehm explains why finalization is necessarily asynchronous. A corollary is that while finalization is a powerful tool, it is very rarely the right tool for a given job.
It's not public (or default access) because it's meant to be called by the JVM internally when the object is garbage collected - it's not meant to be called by anything else. And it's not private because it's meant to be overridden and you can't override private methods.
If i call it twice in my program,
internally what is happening? Will the
garbage collector will call this
again?
Probably yes, but it's hard to imagine a scenario where this would make any kind of sense - the point of finalize() is to do cleanup when an object is garbage collected. And it doesn't even do that well, so it's really something you should avoid altogether rather than experiment with.
finalize() is only used by the JVM to clean up resources when the object is collected. It's reasonable for a class to define what actions should be taken on collection, for which it may need to access super.finalize(). It doesn't really make sense for an outside process to call finalize(), since an outside process doesn't have control over when the object is collected.
Also, I came to know that finalize()
method is called only once. If i call
it twice in my program, internally
what is happening?
You probably ask this under impression of C++ ~destructors. In java finalize () method doesn't do any magic (like clearing memory). It's supposed to be called by garbage collector. But not vice versa.
I recommend you to read correspondent chapter in Joshua Bloch's "Effective Java". It says that using finalizers is a bad practice and can cause performance and other issues, and there are only several cases when they should be used. The chapter begins with next words:
Finalizers are unpredictable, often
dangerous, and generally unnecessary.
I think the reason why finalize is protected would be that maybe it's overridden by some classes in the JDK, and those overridden methods are called by JVM.
Related
I get the gist of reference objects in Java, and the basic differences between soft, weak, and phantom reference objects.
However, I don't fully understand the following points from the API docs
From the API doc for WeakReference<T>:
"Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed."
Now, the terms in bold haven't been explained anywhere in the API docs, so I wonder what they precisely mean, especially in relation to the more or less deprecated Object.finalize() method's notion of finalization.
From the API doc for Reference<T>:
public void clear(): "This method is invoked only by Java code; when the garbage collector clears references it does so directly, without invoking this method."
public boolean enqueue(): "This method is invoked only by Java code; when the garbage collector enqueues references it does so directly, without invoking this method."
Again, I don't know what is meant by "Java code" in above 2 quotes: The JVM internal code to which I have no access? Or, the JDK code to which I have readonly/browsing access? Or, the end-user's own Java code?
The "directly, without invoking this method" part tells me that JVM has no need to call these methods. On the other hand, the "only by Java code" part tells me that it is not the end-user's Java code but rather the JVM's (if it meant end-user code, then we'd be finding this phrase littered in all of the API doc for almost every method of every Java class!). So which interpretation is right and who can call this function?
"Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed."
These are all stages in the Garbage Collection process. Objects first get marked as finalizable to say that there are no strong references to them. Then finalize() is called and they are marked as finalized, and then finally the memory is reclaimed.
public void clear(): "This method is invoked only by Java code; when the garbage collector clears references it does so directly, without invoking this method."
This is saying that when you as a programmer decide to clear a reference then the clear() method is used to do that, however if you were to subclass WeakReference and override the clear method you would NOT see the JVM calling that method when the object was removed.
The quote for enqueue is essentially saying the same thing. It is a warning that you cannot interact with the workings of the GC by overriding these methods.
"finalizable, finalized, and then reclaimed." means garbage collected.
"only by java code" means called from your program itself (including the JDK) - i.e. you may have some code somewhere that calls ref.clear();. It also explains that the GC (i.e. the JVM) does effectively clear the reference but with a different mechanism that does not call the clear method. For example, if you override clear to be a no-op, the GC will still be able to "nullify" the reference.
Making every object lockable looks like a design mistake:
You add extra cost for every object created, even though you'll actually use it only in a tiny fraction of the objects.
Lock usage become implicit, having lockMap.get(key).lock() is more readable than synchronization on arbitrary objects, eg, synchronize (key) {...}.
Synchronized methods can cause subtle error of users locking the object with the synchronized methods
You can be sure that when passing an object to a 3rd parting API, it's lock is not being used.
eg
class Syncer {
synchronized void foo(){}
}
...
Syncer s = new Syncer();
synchronize(s) {
...
}
// in another thread
s.foo() // oops, waiting for previous section, deadlocks potential
Not to mention the namespace polution for each and every object (in C# at least the methods are static, in Java synchronization primitives have to use await, not to overload wait in Object...)
However I'm sure there is some reason for this design. What is the great benefit of intrinsic locks?
You add extra cost for every object created, even though you'll
actually use it only in a tiny fraction of the objects.
That's determined by the JVM implementation. The JVM specification says, "The association of a monitor with an object may be managed in various ways that are beyond the scope of this specification. For instance, the monitor may be allocated and deallocated at the same time as the object. Alternatively, it may be dynamically allocated at the time when a thread attempts to gain exclusive access to the object and freed at some later time when no thread remains in the monitor for the object."
I haven't looked at much JVM source code yet, but I'd be really surprised if any of the common JVMs handled this inefficiently.
Lock usage become implicit, having lockMap.get(key).lock() is more
readable than synchronization on arbitrary objects, eg, synchronize
(key) {...}.
I completely disagree. Once you know the meaning of synchronize, it's much more readable than a chain of method calls.
Synchronized methods can cause subtle error of users locking the
object with the synchronized methods
That's why you need to know the meaning of synchronize. If you read about what it does, then avoiding these errors becomes fairly trivial. Rule of thumb: Don't use the same lock in multiple places unless those places need to share the same lock. The same thing could be said of any language's lock/mutex strategy.
You can be sure that when passing an object to a 3rd parting API, it's
lock is not being used.
Right. That's usually a good thing. If it's locked, there should be a good reason why it's locked. Other threads (third party or not) need to wait their turns.
If you synchronize on myObject with the intent of allowing other threads to use myObject at the same time, you're doing it wrong. You could just as easily synchronize the same code block using myOtherObject if that would help.
Not to mention the namespace polution for each and every object (in C#
at least the methods are static, in Java synchronization primitives
have to use await, not to overload wait in Object...)
The Object class does include some convenience methods related to synchronization, namely notify(), notifyAll(), and wait(). The fact that you haven't needed to use them doesn't mean they aren't useful. You could just as easily complain about clone(), equals(), toString(), etc.
Actually you only have reference to that monitor in each object; the real monitor object is created only when you use synchronization => not so much memory is lost.
The alternative would be to add manually monitor to those classes that you need; this would complicate the code very much and would be more error-prone. Java has traded performance for productivity.
One benefit is automatic unlock on exit from synchronized block, even by exception.
I assume that like toString(), the designers thought that the benifits outweighed the costs.
Lots of decisions had to be made and a lot of the concepts were untested (Checked exceptions-ack!) but overall I'm sure it's pretty much free and more useful than an explicit "Lock" object.
Also do you add a "Lock" object to the language or the library? Seems like a language construct, but objects in the library very rarely (if ever?) have special treatment, but treating threading more as a library construct might have slowed things down..
My AP Computer Science teacher tells me not to use static methods because Java garbage collection only affects non-static methods, and therefore static methods that are no longer used will take up extra memory. I'm almost positive that GC should never affect any methods, only objects, but I wanted to be sure before I say anything. So does GC have anything to do with methods?
Assuming she really said methods and not fields then your teacher is wrong on this occasion. As you say, garbage collection is the process of reclaiming memory from objects that have been allocated, the scope of the method that allocated them is irrelevant.
As a side note, static fields are a different matter. Holding objects in a static field (usually) does prevent the garbage collector doing its thing as the class will always hold a reference to it and so it won't be eligible for collection.
use static methods because Java garbage collection only affects non-static methods, and therefore static methods that are no longer used will take up extra memory.
I think you miss understood what he/she said. A method is only unloaded when its ClassLoader is unloaded, in most Java SE programs, that is never.
I think your teacher is wrong. Ask him/her whether he/she thinks that methods are also copied when objects cloned? If he/she say that yes, then he/she is really wrong.
Methods are code and code is static, i.e. it exists in one instance all the time when class exists.
Let's say I have created some resource class with a close() method for cleaning up the resource, and I want to override finalize() to free the resource (and print a warning) if someone has forgotten to call close(). How can this be done properly?
Is it recommended only for native (JNI-allocated) resources?
What happens if you use a reference to another object that has been finalized, from a finalizer? If there are cyclic dependencies I don't see how the garbage collector can prevent you from accessing objects whose finalizers could have been executed.
Are there any better alternatives to overriding finalize() for detecting and/or dealing with resource leaks?
Any other pitfalls to be aware of when implementing a finalizer?
Note: I know that using finalize() is usually bad idea, and that it's not guaranteed to be called, there are several other questions discussing this. This question is specifically about how to implement a finalizer in Java, not about why you should (or shouldn't).
In effective java (2nd edition), Joshua goes in detail in Item #7 about how you can do this. He first suggests that you should almost never use finalizers. However, one reason to use it to only print a log statement saying you have a resource leak. He says one of the draw backs to doing it this way is that someone can extend your class and not properly call the super finalizer. So he suggests to do something like this in the subclass:
// Manual finalizer chaining
#Override protected void finalize() throws Throwable {
try {
... // Finalize subclass state
} finally {
super.finalize();
}
}
This is to ensure that if something breaks in the current class the finally will still get called. This maybe a bad solution because it depends on the person who is subclassing your class. An alternate solution is to use a guardian object file to get this done. This looks like:
// Finalizer Guardian idiom
public class Foo {
// Sole purpose of this object is to finalize outer Foo object
private final Object finalizerGuardian = new Object() {
#Override protected void finalize() throws Throwable {
... // Finalize outer Foo object
}
};
... // Remainder omitted
}
This is a cleaner approach because you know that no one can override that functionality.
The suggested way to closing resources is still implementing Closeable and make sure it is up to the user to close. As Josuha suggests, you shouldn't do any time sensitive operations in the finalize method. The JVM may choose to run it as sometime in the future. If you are depending on this method to do commits or something important then that is a bad idea.
Is it recommended only for native (JNI-allocated) resources?
No. Your use case is also a valid one for finalizers. I mean logging resource leakage.
What happens if you access another Java object that has been
finalized, in the finalizer?
If you can still access it, it is not finalized. Or maybe I'm missing something in your question.
I understand now. It might be the case that both A and B are eligible for garbage collection and there is a reference between them. It should be no problem as by default finalize() does nothing. If you write for both your objects custom finalize() methods you should write your code independent of the order they are finalized. You should also guard for the reference becoming null as the corresponding object might have been already garbage collected.
Are there any better alternatives to overriding finalize() for
detecting and/or dealing with resource leaks?
I think the most important thing when using finalizers is detecting and logging/warning about the leakage not dealing with it. And the best moment to log this leakage is before the resource object is garbage collected. So finalizers are a natural fit for this.
I want to stress this: I wouldn't use finalizers to deal with a programmer that forgot to close the resource, but to inform him that he need to fix his code.
Any other pitfalls to be aware of when implementing a finalizer?
It seems there is also a performance penalty with objects that have finalizers. You should make a test see how it goes for you. If there is an important performance penalty I would try to imagine a mechanism to use finalizers only at development time to log resource leakage.
And take care when inheriting an object with finalizers as suggested by Amir Raminfar.
One more thing: take a look at the source code of [FileInputStream][1] or [FileOutputStream][2] they use finalizers for the same reason.
I'm a beginner and I've always read that it's bad to repeat code. However, it seems that in order to not do so, you would have to have extra method calls usually. Let's say I have the following class
public class BinarySearchTree<E extends Comparable<E>>{
private BinaryTree<E> root;
private final BinaryTree<E> EMPTY = new BinaryTree<E>();
private int count;
private Comparator<E> ordering;
public BinarySearchTree(Comparator<E> order){
ordering = order;
clear();
}
public void clear(){
root = EMPTY;
count = 0;
}
}
Would it be more optimal for me to just copy and paste the two lines in my clear() method into the constructor instead of calling the actual method? If so how much of a difference does it make? What if my constructor made 10 method calls with each one simply setting an instance variable to a value? What's the best programming practice?
Would it be more optimal for me to just copy and paste the two lines in my clear() method into the constructor instead of calling the actual method?
The compiler can perform that optimization. And so can the JVM. The terminology used by compiler writer and JVM authors is "inline expansion".
If so how much of a difference does it make?
Measure it. Often, you'll find that it makes no difference. And if you believe that this is a performance hotspot, you're looking in the wrong place; that's why you'll need to measure it.
What if my constructor made 10 method calls with each one simply setting an instance variable to a value?
Again, that depends on the generated bytecode and any runtime optimizations performed by the Java Virtual machine. If the compiler/JVM can inline the method calls, it will perform the optimization to avoid the overhead of creating new stack frames at runtime.
What's the best programming practice?
Avoiding premature optimization. The best practice is to write readable and well-designed code, and then optimize for the performance hotspots in your application.
What everyone else has said about optimization is absolutely true.
There is no reason from a performance point of view to inline the method. If it's a performance issue, the JIT in your JVM will inline it. In java, method calls are so close to free that it isn't worth thinking about it.
That being said, there's a different issue here. Namely, it is bad programming practice to call an overrideable method (i.e., one that is not final, static, or private) from the constructor. (Effective Java, 2nd Ed., p. 89 in the item titled "Design and document for inheritance or else prohibit it")
What happens if someone adds a subclass of BinarySearchTree called LoggingBinarySearchTree that overrides all public methods with code like:
public void clear(){
this.callLog.addCall("clear");
super.clear();
}
Then the LoggingBinarySearchTree will never be constructable! The issue is that this.callLog will be null when the BinarySearchTree constructor is running, but the clear that gets called is the overridden one, and you'll get a NullPointerException.
Note that Java and C++ differ here: in C++, a superclass constructor that calls a virtual method ends up calling the one defined in the superclass, not the overridden one. People switching between the two languages sometimes forget this.
Given that, I think it's probably cleaner in your case to inline the clear method when called from the constructor, but in general in Java you should go ahead and make all the method calls you want.
I would definitely leave it as is. What if you change the clear() logic? It would be impractical to find all the places where you copied the 2 lines of code.
Generally speaking (and as a beginner this means always!) you should never make micro-optimisations like the one you're considering. Always favour readability of code over things like this.
Why? Because the compiler / hotspot will make these sorts of optimisations for you on the fly, and many, many more. If anything, when you try and make optimisations along these sorts of lines (though not in this case) you'll probably make things slower. Hotspot understands common programming idioms, if you try and do that optimisation yourself it probably won't understand what you're trying to do so it won't be able to optimise it.
There's also a much greater maintenance cost. If you start repeating code then it's going to be much more effort to maintain, which will probably be a lot more hassle than you might think!
As an aside, you may get to some points in your coding life where you do need to make low level optimisations - but if you hit those points, you'll definitely, definitely know when the time comes. And if you don't, you can always go back and optimise later if you need to.
The best practice is to measure twice and cut once.
Once you've wasted time optimization, you can never get it back again! (So measure it first and ask yourself if it's worth optimisation. How much actual time will you save?)
In this case, the Java VM is probably already doing the optimization you are talking about.
The cost of a method call is the creation (and disposal) of a stack frame and some extra byte code expressions if you need to pass values to the method.
The pattern that I follow, is whether or not this method in question would satisfy one of the following:
Would it be helpful to have this method available outside this class?
Would it be helpful to have this method available in other methods?
Would it be frustrating to rewrite this every time i needed it?
Could the versatility of the method be increased with the use of a few parameters?
If any of the above are true, it should be wrapped up in it's own method.
Keep the clear() method when it helps readability. Having unmaintainable code is more expensive.
Optimizing compilers usually do a pretty good job of removing the redundancy from these "extra" operations; in many instances, the difference between "optimized" code and code simply written the way you want, and run through an optimizing compiler is none; that is to say, the optimizing compiler usually does just as good a job as you'd do, and it does it without causing any degradation of the source code. In fact, many times, "hand-optimized" code ends up being LESS efficient, because the compiler considers many things when doing the optimization. Leave your code in a readable format, and don't worry about optimization until a later time.
"Premature optimization is the root of
all evil." - Donald Knuth
I wouldn't worry about method call as much but the logic of the method. If it was critical systems, and the system needed to "be fast" then, I would look at optimising codes that takes long to execute.
Given the memory of modern computers this is very inexpensive. Its always better to break your code up into methods so someone can quickly read whats going on. It will also help with narrowing down errors in the code if the error is restricted to a single method with a body of a few lines.
As others have said, the cost of the method call is trivial-to-nada, as the compiler will optimize it for you.
That said, there are dangers in making method calls to instance methods from a constructor. You run the risk of later updating the instance method so that it may try to use an instance variable that has not been initiated yet by the constructor. That is, you don't necessarily want to separate out the construction activities from the constructor.
Another question--your clear() method sets the root to EMPTY, which is initialized when the object is created. If you then add nodes to EMPTY, and then call clear(), you won't be resetting the root node. Is this the behavior you want?