I have following snippet of code:
public class Example {
private Integer threshold;
private Map<String, Progress> history;
protected void activate(ComponentContext ctx) {
this.history = Collections.synchronizedMap(new LinkedHashMap<String, Progress>() {
#Override
protected boolean removeEldestEntry(Map.Entry<String, Progress> entry) {
return size() > threshold;
}
});
}
}
Theres is a cyclic dependency between anonymous LinkedHashMap class and Example class. Is this OK or not? Why not? Is it going to be nicely reclaimed by garbage collector?
Is this OK or not?
This is completely fine.
threshold is a field, so it can be referenced from within an anonymous class without any problem. (Had threshold been a local variable, it would have had to be (effectively) final.)
Cyclic dependencies between classes are common and when the dependency graph is small (as in this case) it doesn't pose any problems. The fact that your LinkedHashMap is an anonymous class doesn't matter here.
Is it going to be nicely reclaimed by garbage collector?
The only thing to be wary about regarding memory leaks + inner classes is that a (non-static) inner class has an implicit reference to its enclosing object. This means that if you create lots and lots of instances of the inner class, you can't expect the instances of the outer class objects to be garbage collected.
What that means in this case is that if you leak references to the history map, instances of Example will not be GC'ed.
Related notes:
Considering you're using synchronizedMap it seems like you're working on a multithreaded program. If this is the case, you need to be wary about synchronization and visibility issues for the threshold field.
If possible, try to make the threshold field final
Another option would be to create a named class for your LinkedHashMap and include threshold as a field in that class instead.
You have this dependency anyway, because every object of anonymous inner class has implicit reference to the object of an enclosing class. Java is designed that way, and the nested inner classes have this reference for a reason, so from the language spec standpoint this compiles and looks perfectly normal.
Regarding the (absence of) "design smell", if this anonymous class object is completely encapsulated in Example class, has no distinctive meaning without its enclosing context, and is not leaked anywhere outside of the Example class, there is nothing wrong with referencing fields of enclosing class. You simply use this inner class to group some logic.
If however this object gets leaked out of the enclosing object (you return it via getter, for example), you should either prohibit this or refactor it into a static inner class that receives threshold as a parameter. This inner object holds reference to the enclosing object and may keep it from GC, thus causing a memory leak.
Any time you instantiate a non-static inner class (be it named or anonymous), this inner class' instance automatically gets a reference to the instance of the enclosing parent class.
The above means that if the outer class also holds a reference to the non-static inner class (as is the case in your code), then there is a cyclic dependency between instances of outer class and the non-static inner class (again, both named and anonymous).
The only actual question in this setup is whether your usage of this existing cross reference is legitimate. In your specific case, I don't see any issue - non-static inner class uses an instance variable of the enclosing outer class. Seems Kosher to me.
In this situation, memory leak usually happens when a reference to the instance of the inner class is passed outside of the outer class (which is commonly the case with various Listeners) - since this instance has a reference to the instance of the outer class, the outer class can't be garbage collected. However, I don't think a memory leak can be caused if you just cross reference the outer and the inner classes - they will be garbage collected together.
Cyclic dependency is not bad in it's own, however it may cause some unsuspected memory leaks.
Taken your example as is, it is fine right now as it does what you want it to do.
If you however, or somebody else modifies your code to expose your private:
private Map<String, Progress> history;
Then you may have trouble. What will happen is that you will pass around reference to Example class too, intended or not, as your inner class has implicit reference to it.
I cannot give you direct quote right now, but Steve McConnell in his code complete is calling the cyclic dependencies an anti-pattern. You can read there or i guess google for it, to read about this in great detail.
Another problem i can think of on top of my mind, cyclic dependency is fairly hard to unit test as you are creating very high level of coupling between objects.
In general, you should avoid circular dependency unless you have very good reason not to, such as implementing the circular linked list.
I do not like your solution (even if I agree this could work) :
your class Example should implement Map or extend LinkedHashMap because the instance variable threshold is defined there and refines the concept of LinkedHashMap with its own definition.
your class Example should NOT implement Map or extend LinkedHashMap because the activate method does not refines LinkedHashMap nor Map but uses concepts of Maps.
1+2 => problem of conception.
Related
In the book Java concurrency in practice, when talking about ways to publish an object, there is a mechanism is to publish an inner class instance, and it is not safe because
inner class instances contain a hidden reference to the enclosing
instance
I was wondering how come it is unsafe if you couldn't get the outer class instance through an inner class instance, just because it will effect the GC? I'm confused, whether there is a way to get an outer class instance ,like reflection?
It will not effect GC as you might think. The JVM uses reachability analysis, not automatic reference counting, so both can be freed when none of them are reachable from the starting main's object graph.
It is unsafe -I guess they meant by publishing as serializing and sending-, because through the reference the outer instance will also be serialized causing larger message and or serialization exception (in case it contains something -non-transient- not serializable member or itself is not serializable).
I am not sure the outer object reference name is standardized in any way, so accessing them through reflection requires some trial and error (and obviously testing).
The Java garbage collector is failing to collect dead objects in a program I wrote, and I believe this is because the dead objects have created instances of their inner classes.
When I look at the instances of the inner class in Debug mode, after the creator should have been collected, I find a reference titled this$0, which points to the should-be-dead object.
Is there a way to prevent an Outer.this reference from being created by java in each instance of Inner? This field has no use in the program, and all it does is prevent garbage collection, quickly causing the heap to run out of memory. Moving Inner out of Outer is not an option because it has public data fields that should only be visible to Outer.
Your inner class maintains this$0 so it can get at the private fields and methods of the outer class. If your inner class does not need to use anything in the outer class, you can mark the inner class static to prevent it from maintaining a reference to an instance of the containing class.
Regardless, though, I need my inner class to be non-static, because each instance of it needs to invoke non-static methods that use it's non-static instance data.
In that case, the outer objects shouldn't be garbage collected ... because the outer objects are where that instance data resides!
FOLLOWUP
What would you recommend then? I have no idea how use packages, but I need to create instances of Inner which have public data fields accessible only to Outer, and can survive past the destruction of Outer. Am I out of luck?
Before I answer your question:
"I have no idea how use packages ..." - you ought to learn about them then. Packages and "package private" access are an important part of the Java language.
Now to your question ...
If you want fields only to be accessible to the Outer class (and classes nested within) then you have to use nested or inner classes. (If you try to do this using a package and package-private access, then other classes declared in the same package can also access the fields. However, if that's acceptable, then packages are a simpler way to do this.)
Assuming that you are going to do this using nested or inner classes, then there are two ways to do this:
If you declare the Inner class as private static class Inner, then methods in the Inner class CANNOT call instance methods or access instance fields of Outer ... unless they have a reference to and Outer instance (e.g. passed as a parameter). If Inner is static, the lifetime of instances of Inner and Outer are independent.
If you declare the Inner class as private class Inner, then methods in the Inner class CAN call instance methods or access instance fields of Outer. But the flip side is that the lifetime of an Outer instance and its Inner instances are now dependent. Specifically, an Outer instance will exist as long as at least one of its Inner instances continues to exist. (The reverse is not true ... unless the Outer instance is holding references for Inner instances in (say) a collection-typed field.)
Just to restate what I said previously. If an Inner instance needs to access instance fields or call instance methods on an Outer instance, then it needs an explicit or reference to that Outer instance. That means that the Outer instance is reachable, and is not a candidate for deletion by the garbage collector.
The other point is an instance of Inner won't go away if it is still reachable; i.e. if some part of your running application has a reference to the instance that it could possibly use. In Java, objects DON'T get garbage collected if there is any possibility that they could be used by the running application. Instances of inner/nested classes are not special in this regard.
Actually, there may be a (really nasty!) way to do it break the linkage between the Inner and Outer instances. If you can find all of the Inner instances, you can use reflection to assign null to the this$0 hidden variable in each one. However, if you do that, any code in the Inner class that refers to the Outer instance state will break. If you are going to resort to this kind of nastiness, you are better off declaring Inner as a static class.
About all you can do is make the inner classes static, or not use inner classes at all.
You can, of course, make use of package scoping to limit visibility of fields in the classes without having to resort to inner classes.
I know that internal class has to be static because will link between public and internal classes and internal class will be created all times that created public classes.
And my question how to check it?
I mean write some simple application and make some loop for creating objects and see that objects do not deleted by GC in some profiler, Can I to do something like that nad some one done it?
Thanks.
internal class will be created all times that created public classes
If you mean that an instance of the inner class will always be created when you create an instance of the outer class, that is not true.
You can have outer instances with no attached inner instances, and the same outer instance can have any number of attached inner instances (and of different inner classes, too).
It is (somewhat) the opposite rather: When you create an instance of the (non-static) inner class, that instance will contain a reference to its outer instance (but that is a reference to an already existing object, not a new one: You cannot create the inner instance without having the outer one first).
This can be done using static analysis. If you are using Eclipse check out the FindBugs plugin, it can detect the lack of static inner classes and a bunch of other useful problems.
An internal class does not have to be static. In fact, one of their most common manifestations - anonymous inner classes - are never static.
The phrase "static class" does not cause a class to get created at runtime - classes are only "created" once, by the classloader, when they are loaded. What you meant to say is that the instance of the internal class will be created every time an instance of the outer class is created. And this too is false in general (see Thilo's answer).
Don't worry - I misunderstood internal classes in exactly the same way as you when I first learned about them!
A non-static inner class will have an implicit (i.e. it's there automatically, you don't declare it) reference to the instance of the outer class which created it. This will prevent the instance of the outer class being GCed as long as the instance of the inner class exists, just like a normal Java reference.
A static internal class will not have such a reference, because it is not created by an outer instance but by the classloader.
I have a large tree-like data structure of objects which behave mostly identical but differ in one or two methods that calculate some keys used to navigate through the structure. The divergent behaviour depends on where the objects are in the structure.
I was starting out with an abstract base class and have several subclasses that implement each type of behaviour. This gives me around ten subtypes which are a) hard to name intelligently and b) look a little unwieldy in my project's source folder, both because they are so similar.
I would prefer having a single factory class that doles out instances of anonymous subclasses on the fly. This would give me a lot of flexibility and open the door for a lot of nice improvements, such as sharing data and parametrizing stuff and would look a lot cleaner in my code structure. However, the whole thing is very sensitive to memory footprint and memory access time, and I'd have lots of these objects. Do I have to consider any disadvantages or pecularities of anonymous classes?
Like non-static inner classes, anonymous classes have a hidden reference to the class they're defined in, which can cause problems if you use serialization and of course prevent objects of the outer class from being eligible for GC - but that's unlikely to be a problem if you do it in a single factory class.
Anonymous classes are not different than named classes.
But yes, having many objects can impact your memory footprint, and performance (garbage-collection).
From what you tell, I wonder if it would be possible to split your class in two parts:
All the constant methods in one class (no subclass of this class).
All variable methods (see later) are encapsulated in a Position interface. You can have a few classes that implement it. The objects of these classes would have no state, so they can be shared instances which is excellent for performance and memory).
Variable methods : calculate some keys depending on the position in the structure.
As mentioned an anonymous inner class usually has a hidden reference to the class in which it is declared. However, you can eliminate this by declaring the anonymous class from inside a static method (simple, and not perfectly obvious).
The major disadvantage to this technique is that the classnames seen in jars will be numbered (like "MyClass$0.class") and not easily identifiable in stacktraces (except of course by using the line numbers) and without toString() methods not easily identifiable in your own println statements.
Declaring static inner classes is a great technique. It will eliminate all these disadvantages and keep your file hierarchy compact. Also consider making these inner classes private or final unless you need to extend them.
A class is a class. It doesn't matter whether it's a "top-level" classes, a regular inner class, a local inner class, or an anonymous inner class.
Non-static inner classes, or inner classes that access private members of their enclosing class will have a tiny bit of extra code in them. To non-static inner classes, the compiler adds a member variable that references the enclosing instance. If an inner class accesses any private members of the enclosing class, the compiler will synthesize an accessor in the enclosing class with "package-private" (default) accessibility.
This morning my boss and I had a long and ultimately fruitless discussion about this, in the context of trying to diagnose performance problems with a web application. We didn't really come to any conclusions.
I think we're right in thinking that Serializable non-static inner classes have issues, but we're not sure precisely what the issues are or what exactly to avoid (we reasoned that we couldn't always simply avoid it). Can anyone suggest any guidelines for not getting in trouble with this issue?
An inner class holds a reference to its outer class, so attempting to serialize the inner will also serialize the outer -- as well as any other objects that the outer might hold. This could result in a huge object graph. Or it could fail, if the outer has state that can't be serialized (such as an InputStream object).
That said, there are times when you have to make inner classes Serializable, even if you never plan to serialize them. For example, if you're working with Swing.
If you do plan to serialize these objects, I'd question why they'd need to be inner classes irrespective of performance. Generally, you're only going to serialize data containers, and such containers rarely (if ever) need a reference to some "parent" class. Consider making these objects nested (static) classes rather than inner classes.
Just being aware that a serialized inner class has an implicit reference to its containing object will go a long way. That reference does have a number of implications:
The reference is automatically generated, so it can't be transient
The outer class must be serializable
The outer class will be automatically serialized with the inner class
The outer object can't be disassociated from its inner object
Probably the main guideline I can dredge up is "don't serialize inner classes except from their containing object." I can't think of any more gotchas.
A thought. If your outer class includes a (non-transient) collection of instances of the inner class, then each time you serialise one of the inner class instances, you will actually pull all of them into the serialization.
You can make the class Externalizable and write your own custom writeExternal and readExternal methods which only send the fields you want.
http://java.sun.com/javase/6/docs/api/java/io/Externalizable.html