As per the definition in Java. If class doesn't occupy memory and just acts like a template, then why are we creating objects(main method) inside curly braces of class. Doesn't that mean now class also occupies memory because of objects present inside of it?
Trying to understand the definition of a class
There are three concepts to keep separate here: the class, the instance, and the stack.
class SomeClass {
static int staticValue = 0;
/* non-static */ int instanceValue = 0;
int someMethod() {
int stackValue = 42;
SomeClass instance = new SomeClass();
// ...
}
}
The class acts as a template, yes. In some languages other than Java, the class takes up no memory of its own: it merely describes the memory layout of the class's instances. For a beginner definition of OOP concepts you can think of that as true.
In Java this is not quite true for three reasons:
There is an object instance for SomeClass, accessible via SomeClass.class, which does take up memory. This instance allows you to look up information about the class itself, which is sometimes called "reflection".
The static field staticValue is shared among all instances of SomeClass, so in a sense the class takes up a small amount of memory to contain this shared value.
SomeClass contains methods like someMethod, and that code has to be in memory in order to run. If you're willing to consider code as requiring memory, and that the code is associated with the class, then the class consumes memory. People talking about OOP concepts aren't usually talking about the memory consumed by the code itself, though.
This can be compared to instances of the class SomeClass, which at a minimum contain a separate value of instanceValue for every instance you create. Instances don't have their own code, and do (in Java) contain a reference to their Class instance accessible via getClass().
Finally, the method someMethod and your main example do use references and local variables that consume memory, but in a different place than the instances or classes. This place is called a "stack", in part because as you call methods and those call further methods, the stack grows like a stack of papers on a desk. This means that there may be many copies of stackValue existing at once, one for each time you have called someMethod that hasn't finished yet. Each value of stackValue is discarded whenever its corresponding invocation of someMethod returns. These aren't directly tied to classes or instances, other than that they are code that might be considered associated with a class as in #3 above. Disregarding the memory consumed by the compiled code itself, the instance does not contribute to SomeClass or its instances consuming any more memory in ways that matter to OOP.
(Instances created with new are not a part of a "stack" but rather are part of the "heap", at this level of explanation, and that includes the SomeClass.class instance and any instances of SomeClass. Some languages require careful management of the heap's memory, but Java manages it for you through a process called garbage collection. Primitives like stackValue and the reference named instance are kept on the stack, though.)
Related
I'm looking at chapter 1 of Effective Java(3th ed, Joshua J. Bloch)
and It says using a static method is better than constructor.
But I understand that static is loaded in memory when classloader initiates,
and in normal case the static members are not removed by garbage collector
until the class unloaded.
So if I understood right, when I use more and more classes which have static method,
It consumes more memory, am I right?
Is that memory timid to concern, or there are other reasons to use them nevertheless?
Static member variables are not garbage collected (assuming the classloader is still alive), since the class itself will always hold a reference to it. The same is not true of methods.
Static methods (a.k.a factory methods) are sometimes preferred for a few reasons.
You can name them how you want: Imagine the following constructor: public Hyperlink(String string){...}. It is not clear what the string actually refers to. Is it the text to be made into the link? Is it the URL? Imagine instead the static factory public Hyperlink.fromURL(String string){...}. Much clearer.
Caching - the new keyword always creates a new object, or it throws an exception. There is no way to return an object that already exists in a cache somewhere. With a static factory, you could first check that the object does not already exist, and retrieve it if it does, and call a constructor if it doesn't.
Polymorphism - Consider the classes Animal and Dog extends Animal. The constructor public Animal(String species){...} always returns an Animal object. Dog dog = Animal.fromSpecies(String species); however, is valid.
There are of course reasons to use constructors, but personally, I will always go for a static factory method for anything vaguely complex.
Concerning memory usage, the cost of storing methods, except in very large projects or very constrained systems is negligible. Load time is another issue, but not one that is improved by avoiding static methods.
According to the following link the java stack frame contains local variables, operand stack and the current class constant pool reference.
http://blog.jamesdbloom.com/JVMInternals.html
Also From Oracle "Structure of JVM" Section 2.6.3. "Dynamic Linking - Each frame (§2.6) contains a reference to the run-time constant pool (§2.5.5) for the type of the current method to support dynamic linking of the method code."
I have also read that the object in the heap also has a pointer/reference to the class data.
https://www.artima.com/insidejvm/ed2/jvm6.html
The stack frame will contain the "current class constant pool reference" and also it will have the reference to the object in heap which in turn will also point to the class data. Is this not redundant??
For example.
public class Honda {
public void run() {
System.out.println("honda is running");
}
public static void main(String[] args) {
Honda h = new Honda();
h.run(); //output honda is running
}
}
When h.run() is going to be executed, jvm will create a new stack frame and push h on the stack frame. h will point to the object in heap which in turn will have a pointer to class data of Honda. The stack frame will also have current class constant reference. Is this correct? If not please shed some light on this.
Is this not redundant??
Maybe it is redundant for instance methods and constructors.
It isn't redundant for static methods or class initialization pseudo-methods.
It is also possible that the (supposedly) redundant reference gets optimized away by the JIT compiler. (Or maybe it isn't optimized away ... because they have concluded that the redundancy leads to faster execution on average.) Or maybe the actual implementation of the JVM1 is just different.
Bear in mind that the JVM spec is describing an idealized stack frame. The actual implementation may be different ... provided that it behaves the way that the spec says it should.
On #EJP's point on normativeness, the only normative references for Java are the JLS and JVM specifications, and the Javadoc for the class library. You can also consult the source code of the JVM itself. The specifications say what should happen, and the code (in a sense) says what does happen. An article you might find in a published paper or a web article is not normative, and may well be incorrect or out of date.
1 - The actual implementation may vary from one version to the next, or between vendors. Furthermore, I have heard of a JVM implementation where a bytecode rewriter transformed from standard bytecodes to another abstract machine language at class load time. It wasn't a great idea from a performance perspective ... but it was certainly within the spirit of the JVM spec.
The stack frame will contain the "current class constant pool reference" and also it will have the reference to the object in heap which in turn will also point to the class data. Is this not redundant??
You missed the precondition of that statement, or you misquoted it, or it was just plainly wrong where you saw it.
The "reference to the object in heap" is only added for non-static method, and it refers to the hidden this parameter.
As it says in section "Local Variables Array":
The array of local variables contains all the variables used during the execution of the method, including a reference to this, all method parameters and other locally defined variables. For class methods (i.e. static methods) the method parameters start from zero, however, for instance method the zero slot is reserved for this.
So, for static methods, there is no redundancy.
Could the constant pool reference be eliminated when this is present? Yes, but then there would need to be a different way to locate the constant pool reference, requiring different bytecode instructions, so that would be a different kind of redundancy.
Always having the constant pool reference available in a well-known location in the stack frame, simplifies the bytecode logic.
There are two points here. First, there are static methods which are invoked without a this reference. Second, the actual class of an object instance is not necessarily the declaring class of the method whose code we are actually executing. The purpose of the constant pool reference is to enable resolving of symbolic references and loading of constants referenced by the code. In both cases, we need the constant pool of the class containing the currently executed code, even if the method might be inherited by the actual class of the this reference (in case of a private method invoked by another inherited method, we have a method invoked with a this instance of a class which formally does not even inherit the method).
It might even be the case that the currently executed code is contained in an interface, so we never have instances of it, but still a class file with a constant pool which must be available when executing the code. This does not only apply to Java 8 and newer, which allow static and default methods in interfaces; earlier versions also might need to execute the <clinit> method of an interface to initialize its static fields.
By the way, even if an instance method is invoked with an object reference associated with this in its first local variable, there is no requirement for the bytecode instructions to keep it there. If not needed, it might get overwritten by an arbitrary value, reusing the variable slot for other purposes. This does not preclude that subsequent instructions need the constant pool, which, as said, does not need to belong to the actual class of this anyway.
Of course, that pool reference is a logical construct anyway. Implementations may transform the code to use a shared pool or not to need a pool at all when all references have been resolved already, etc. After inlining, code may not even have a dedicated stack frame anymore.
An instance variable is one per Object, every object has its own copy of instance variable.
A static variable is one per Class, every object of that class shares the same Static variable.
class MyStaticClass{
private static int myStaticInt;
public static int getMyStaticInt() {return myStaticInt;}
}
class MyInstanceClass{
private int myNonStaticInt;
public int getMyNonStaticInt() {return myNonStaticInt;}
}
Is there a performance difference between either? Is it more expensive to call one over the other?
int i = MyStaticClass.getMyStaticInt();
OR:
int i = new MyInstanceClass().getMyNonStaticInt();
It's not a matter of performance. static and instance variables have a different purpose.
Using
int i = new MyInstatnceClass().getMyNonStaticInt();
is almost certainly useless, since each time you call new MyInstatnceClass() you create a new MyInstatnceClass instance, having a new myNonStaticInt instance variable. Since you are not keep a reference to the created instance, you cannot retrieve the same instance variable twice, which makes it useless.
If you need a single copy of a variable to be shared across all instances of the class, static variable is the way to go.
That said, the latter call is also more expansive, since it involves creation and initialization of an instance of your MyInstatnceClass class (in addition to loading and initialzing the class if it's the first access that class).
On the other hand, MyStaticClass.getMyStaticInt() only loads and initializes the class MyStaticClass if it's the first access of that class. It doesn't have to create any instance of that class.
Since instance methods can be polymorphically overridden, a very naive JVM implementation must at least initially use a virtual mehod table to find the appropriate method to call. Classes themselves, however are not polymorphic and class methods cannot be overridden. Due to this, they have a simpler lookup mechanism.
However, real-world JVMs are incredibly smart and can tell which methods are never overridden and optimize this lookup away. In other words, in all but the most contrived instances with non-existent JVMs will there be a difference in performance. Instead, use static methods to represent functionalities relevant to the entire class of objects itself rather than to a single instance thereof.
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.
I come from operating systems and background of C where the world is simple when code is compiled. Need to deal and understand stack, heap text section etc.
When I started learning Java(I do know about JVM and garbage collector), I got amused by static methods. As per my understanding all the instances of a class do get created in the heap and then do get cleaned. However, for a static method, you don't need an instance of the class.
So, can some one please explain how non static methods and static methods differ in memory model. Do both of them reside in the text section of the memory. Or I am messing up things completely.
Thanks
In Java, the bytecode for the classes (and that includes their methods, both static and instance) is part of the heap (usually in a special "permanent generation" section for long-lived objects).
Classes can be garbage-collected, too, but this usually does not happen much (only when the class was loaded from a non-system classloader and that whole classloader becomes obsolete, for example when a web application is unloaded).
However, for a static method, you don't need an instance of the class.
Right. But all methods are part of the class definition and loaded together when the class is loaded. Even if you never make an instance of a class, the code for all instance methods will be loaded into heap memory.
And then there is JIT compilation to native code: With Hotspot, the bytecode for frequently used methods is compiled further into native machine code. The result of that does go somewhere outside of the heap into native memory, and that only happens for methods that are actually being used (static or not).
Your understanding that all instances of a class get created in the heap...
Not exactly correct, all classes get compiled into object byte code, otherwise the JVM has nothing to execute. Instance and static methods all generate the same object byte code. Even non-static classes only generate a single version of their object byte code. All instance classes have their own pointer to where their execution is in that single copy of byte code. The real difference is in the data members of the class. Each instance of a non-static class has to have its own copy of all the non-static data members (variables), but static data members only have a single copy in memory since static data members of a class are shared by all instances of that class static or non-static.
A static class or the static data members of a non-static class all have a single copy of themselves in memory.
A non-static class still has just a single copy of its object code in memory, it is only the non-static data that gets a copy in memory for each instance.