Java memory model for static methods - java

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.

Related

In oops concept does class occupy memory

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.)

Do Java classes have an instance on machine (JVM) level if they contain only static methods and fields?

Do Java classes have an instance on machine (JVM) level if they contain only static methods and fields?
And if yes, what are the effects of static methods and fields when doing multithreading? Any rules of thumb?
Yes, for each loaded class in the JVM there is an instance of java.lang.Class. It does not matter whether they only contain static methods/fields or instance methods/fields as well.
And this does not have any extra impact on multi-threading beyond what instance fields and methods already have. That is, as long as you realise that the value of a static field is shared between all instances.
If you want to synchronize, you need to synchronize on the java.lang.Class instance for the class (or if the method is a static method inside said class, it can have the 'synchronized' modifier on the static method to have the same effect as synchronizing on the java.lang.Class instance for the class).
One extra thing to note is that a class with the same name can be loaded by more than one classloader at the same time in the JVM- hence classes in Java are not uniquely identifier by their fully-qualified name, instead they are uniquely identifier by the combination of java.lang.ClassLoader instance used to load the class, and the fully-qualified name.
Static methods and variables are at the class level in Java, not instance level.
All shared, writable state needs to be synchronized and thread safe, regardless of static or instance.
There are no such thing as "static classes" in java. There are inner static classes, but i presume that your question its not about this type of classes.
Classes are loaded once per classloader not per Virtual Machine, this is an important diference, for example applications server like tomcat have different classloaders per application deployed, this way each application is independent (not completely independent, but better than nothing).
The effects for multithreading are the effects of shared data structures in multithreading, nothing special in java. There are a lot of books in this subject like http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601 (centered in java) or http://pragprog.com/book/pb7con/seven-concurrency-models-in-seven-weeks (that explain difference concurrency models, really interesting book)
Yes, a class with static fields and methods has exactly one instance, which is accessed through a static call.
If you use static methods, the variables declared within the method are isolated and don't need to be synchronized (the same as in C#: C# : What if a static method is called from multiple threads?).
But when your classes have static variables and you access them within a static method, there is a trade off: When doing multithreading, the access to the static variables must be synchronized. That's the reason why the singleton pattern doesn't work as good as some believe: Instantiation costs, even more if it's only singlethreaded.
Rules of thumb? Static methods with no static class variables are always good. But static classes with variables can become very evil when doing multithreading. Therefore beware of static bottlenecks!

Android static class vs non-static class memory performance

I've created a class which was static first, this class does not persist state (does not keep context or any variables) is just a list of functions.
But the class is not very used in the app so I decided to make class instantiable.
Why?
Because I think an instantiable class would use less memory as it is not available during the whole app life cycle.
Is this right?
A static class uses more memory than a non-static class?
Thank you
I think you've misunderstood how classes work. Any kind of class is "available" throughout the lifetime of the app. Memory used for the class itself (the methods etc) is very different to memory used by instances. Unless you actually create an instance of the class, it's irrelevant. And even static classes can be instantiated - it's just that they don't maintain an implicit reference to an instance of the enclosing class.
If your class doesn't actually require an implicit reference (i.e. it doesn't use it) then make it a static nested class - or pull it out as a top-level class anyway. (Nested classes can be a pain sometimes - the rules around top-level classes are simpler.)
A static class as such doesn't use more memory than a non static one. All classes are always available in an application - you can always use a static class or create an instance of a non static one.
If you have only methods in your class (which are of a helper method types) a static class is more convenient to use (no need to create an instance) and won't affect your memory usage.

Memory management utilization in java

I am having a simple query.Basically its a theoritical question.I need to clear this idea.I have not found any suitable answer to it.The question is very simple.Suppose we have a class named as A
class A{
......
}
Now from my main function i am creating one object of A.
A obj = new A();
now after creating the object i will be able to access any methods,variables present in the class.
But for static methods or variables we can achieve this directly by using class name like
A.methodname();
now my question is if we are creating one object of any class then memory will be allocated for this.Now if we are using static methods are directly calling them via class name then we are not creating any objects,so in that case memory should not be allocated.But without allocating the memory how does we access the methods or any variable name?Using reference also require some memory allocation.so please explain how in this case memory allocation is happening or how we are accessing the methods or variables in the class.
Now if we are using static methods are directly calling them via class name then we are not creating any objects,so in that case memory should not be allocated.
Actually, you do. It is JVM dependent but the HotSpot JVM creates a special object for all static fields. You can see this object in a heap dump.
Making this an object makes it easier for the GC to trace which objects are being used. This class object is discarded when the ClassLoader is unloaded.
This is done by class loading.
We do not have any instance of object, but we have a class code loaded into memory so in fact there is memory allocation.
Static functions can only access static variables, and the memory for that will already have been allocated.
Static members (methods and variables) are allocated by the JVM when the class is loaded.
without allocating the memory how does we access the methods or any variable name?
You cant access an instance method or variable from an static method. It wont compile if you try.
From an static method, you can only access other static methods or static variables, (wich are allocated at class load time).
All the static variables of a class are loaded into memory at the time of class loading where as the instance variables are allocated with memory everytime you create a new object of that class.
However, the static variable values are not specific to a instance of an object but there are shared by all the objects of a class where as the instance variable values are specific to an instance(class object).
That is the reason you can access the static variable using class name as they are already loaded into the memory where as the instance variables and methods need object creating to access them.
Cheers!
For static during a class loading a memory allocation is done in permanent generation.Its initialization occurs only once .It is related to class not object.

I want to know when a program written by Java is running,its classes will be all loaded on the main memory?

When a program written in Java is running, will all of its classes be all loaded into the main memory? If so, isn't it a waste of RAM?
No it's fine, because of virtual address space and virtual memory. Read these:
http://en.wikipedia.org/wiki/Virtual_memory
http://en.wikipedia.org/wiki/Virtual_address_space
Virtual memory means that you can load a large amount into memory and the unused sections are saved to disc and are moved out of physical RAM.
Virtual address space means that each process (one example of a process is your Java program) has its own address space, so it does not 'steal' addresses from other processes.
Only classes that are referenced during a particular execution are loaded. Most large Java programs will frequently run with many of the classes not loaded as those classes serve various scenarios not exercised by that particular process.
Classes in the standard library are handled the same as application classes. For instance, if your application does not reference AWT, no classes in AWT packages will be loaded.
Java language spec contains the wording which explicitly precludes eager initialization of classes.
JLS Section 12.4:
A class or interface type T will be
initialized immediately before the
first occurrence of any one of the
following:
T is a class and an instance of T is
created.
T is a class and a static
method declared by T is invoked.
A
static field declared by T is
assigned.
A static field declared by T
is used and the field is not a
constant variable (§4.12.4).
T is a
top-level class, and an assert
statement (§14.10) lexically nested
Note my use of the term "initialization". A class is initialized as part of constructing Class object, when parsing the binary data that defines the class.
There is nothing precluding a particular ClassLoader implementation from loading the binaries of all the classes that it sees into memory, but it cannot fully load those classes until they are requested without violating JLS.
For a common ClassLoader implementation, see URLClassLoader.

Categories