I am a beginner in Java and I had completed C++.
In C++,the memory allocation for member functions is done at the time they are declared as a part of a class and not when the objects are created,when the objects are created,then only the memory allocation for the instance variables is done,that is for every object memory allocation for instance variable is done seperately and the member functions are shared commonly by all the objects.
In case of instance variables,I know the same case happens in java,but what happens in case of member functions?
In C++;
For e.g. if we have 2 instance variables a and b,and we had created 3 objects x,y,z and let us say we have a member function getData(),
then all the 3 objects have a seperate copy of the two instance variables a and b,but share a common copy of getData().
For instance variables,same is the case in java,but what for member functions?
In Java, the bytecode for the methods exists only once for a class; no copy of the method's bytecode is made for every object. That would be unnecessary and wasteful; the bytecode does not change while the program runs.
So it works the same as what you say for C++:
... the member functions are shared commonly by all the objects.
In Java, member functions are loaded on-demand by the classloader. Since the entire Java standard library is available alongside any Java program, and the program itself may contain any number of classes, this is necessary in order to keep program start times in the range of sanity.
So any time the program needs a class in any way (e.g. to access a static variable or method, or to create an instance of an object) that isn't already loaded, the Java classloader loads that class, which includes the class's member functions. Then, once that class is loaded, it doesn't need to be loaded again if it's needed in the future, because similarly to what you noted in your question, only one copy of the class bytecode is necessary at any given time.
To avoid accumulating more and more loaded classes as the program runs, Java uses garbage collection to unload classes that it knows it can safely unload, similarly to how it uses garbage collection for program data. Those classes can of course be reloaded later if they are needed again. There are, of course, situations in which unloading a class wouldn't work due to the risk that reloading it would cause static variables/code to be reinitialized/run.
This ability to unload and reload classes can also be put to use in debugging: IntelliJ IDEA has a HotSwap feature that allows you to edit and recompile a class while the program is running, unload that class, then reload the new bytecode so you can quickly test ideas. (Wow, I just realized that totally sounded like an advertisement. I'm not affiliated with JetBrains, in case you're wondering.)
Related
I've been looking to no avail searching different sites because all the search results want to tell me how to compute the size of an object, not of a class.
When we define a class (with a .class file in a jar/war) and it gets loaded into the JVM, how much space does that take up? Obviously it depends on the actual things in the class, a class with more fields has more metadata to store. But if we say for example the class had 10 integer fields and 10 reference fields to other objects:
How much extra space would it take up in the JVM to have say, 1,000 of those classes (all extending the same base class)?
Would it change if they were anonymous classes instead of defined classes?
Well every Class itself is an object. So an indicative size would be to call Instrumentation.getObjectSize() on the class itself.
You can follow the tutorial here:
https://www.baeldung.com/java-size-of-object
And then if you want to check the size of MyClass you can do:
InstrumentationAgent.getObjectSize(MyClass.getClass());
This doesn't mean it is the only memory associated with this class, because the class loader, garbage collector and other internal workings of the JVM might keep other meta information about the class.
The answer will most definitely depend on JVM implementation (including version of such implementation, platform etc). There is no one number you can get.
As for anonymous inner classes, these still have class names generated for them, so this should have zero impact.
Since in C++ all the methods (non-static and static) are global (stored in static memory area), I am wondering if it is also true for Java.
My guess is that the way Java stores object methods should be the same as in C++, since you can not have non-static methods stored in dynamic or stack, which will be memory-consuming.
All code is stored 'globally'. It has nothing to do with the heap or the stack. They are for data.
When you load a class, a JVM-internal representation of the class is created. This contains, or has pointers to, all the data in the .class file, including the bytecode sequences for the individual methods.
As a part of the class loading process, a table of instance method pointers is created, with one "slot" for each method in either that class or (recursively) it's superclass. The pointers to the individual bytecode sequences (and, should the code be JITCed, the machine code) are placed in that table.
There is only one instance of this table (and the data it points to) for all the instances of the associated class.
I have read a class is a model for creating objects and does not exist physically whereas Objects are real. But we are creating variables inside a class and are even manipulating them.
How is that possible when class does not exist physically?
When is the memory created for these variables?
Where is the memory created for these variables?
If you mean static class variables, they are quaranteed to be initualized and any static initialization code inside class is quaranteed to be run, before the class is used. Exactly when, that is not specified IIRC, and different JVMs may do it at different time. They are basically same thing as global variables in languages which have those.
So to reiterate: static stuff exists and is initialized before it is first used. JVM implementation takes care of that.
But there is an object: instance of the class object, which is subclass of class Class.
Addition: In fact, in Java classes exist so concretely, that they can be serialized, transferred over network to different JVM, deserialized there, objects of the class created there and code executed. Simple example of this are vanilla Java applets running in browser. Another example is slave nodes in Jenkins/Hudson CI system, where the slave program is very small and only contains code to receive, deserialize and instantiate both classes and objects of these classes, sent by the master server they're connected to.
Try thinking of it this way. This is NOT an accurate explanation of exactly how any Java runtime does this, but a way of thinking of the class/object duality that may help you.
When you write a class X, you describe both code and data. The runtime will need only one copy of some things -- the code and static variables, for instance -- and one copy per object of other things, like the instance variables. You describe both these things in the class file you write, even though they will be stored separately.
Think of the one-copy-per-class things as all being stored in a block of memory together -- it would be called a struct in C. In Java, the first time the class X is referenced in your program, the runtime allocates this block of memory and associates it with the class X.
When the program executes a statement such as "X x1 = new X()", the runtime allocates another block of memory (or struct) containing all the instance variables, and keeps a separate pointer to that associated with the x1 variable.
Now, when the program executes something like "Arc arc = x1.getArc();", the runtime uses the first pointer to reference the code in the method getArc(), and the second pointer to reference the instance variables associated with x1, and executes the indicated code using those instance variables.
OO programming provides this way of associating data with code that manipulates it, allowing us to organize the program as 'objects' of combined code and data. The runtime does the business of keeping track of the different copies of things for us.
And I think it's inaccurate to say the class will not exist, it just won't exist in the form in which you wrote it.
Classes do exist Physically in the JVM at runtime. The explaination that you read was trying to labour point A while leaving the rest of the detail for later. School and books do this all of the time.
Within the Oracle JVM classes have physical representation from the moment that they are loaded. Infact every object has a pointer to that class and many objects can point at the same class.
I wouldn't think of a class or objects as physical things, that seems confusing to me. A class is often described as a blueprint for an object. Objects must be instantiated (created) using the new keyword, when an object is instantiated the class of the object is used as a blueprint to create the basic default object. The object may then be manipulated, even at runtime, by referencing the location in memory where it is stored and using methods inside the object's class to manipulate the fields inside the object's class, at least this is the way it usually should be done, its what's known as encapsulation and is incredibly important in OOP so if you're not familiar with encapsulation I would recommend looking into it.
I mentioned an object can be manipulated at runtime, that is a major difference between an object and a class. Classes can as well using something called reflection but that's another topic for another day. A variable or field is sometimes described as an address, it is a reference to the location in memory where the object is stored. Objects are not accessed directly, they are referenced through variables.
JLabel label;
The code above is setting aside a location in memory to store a JLabel object when it is instantiated with the new keyword. So far there has not been an object created, we have declared a variable which is a reference to the location in memory where our object WILL be stored when it is created. We are not going to access our JLabel object directly, we are going to use the 'label' variable we've created to reference the actual object in memory. So if we create two JLabel objects and instantiate them, like this...
JLabel label;
label = new JLabel();
JLabel anotherLabel = new JLabel("this is another label");
we now have two JLabel objects. The first object first declares a variable to reference the object then instantiates it on a separate line. The second object declares the reference to it and instantiates it all in one line. You can create objects either way and there are different reasons for using both of these methods. When an object is created at least one of its constructor is called the first object calls the constructor inside of the JLabel class that takes no parameters; The second object uses the constructor inside the JLabel class that takes a String and creates the object displaying the text passed in to the constructor.
Now imagine the program is running and we want to change the first object so it will display some text because it currently is blank since we used the constructor that doesn't take any parameters. We can manipulate the object using the setText(String) method like this.
label.setText("now the first label displays text");
We have not altered the JLabel class in any way by using that method, however we have changed the object so now it displays text. I'm probably going to lose a bunch of reputation points, or whatever they are, for this answer because I probably didn't explain every detail exactly correct but I answered this question because you're asking something that was pretty difficult for me to understand for a long time, probably more so than most because I've never taken a programming class. There's so much to this I cant possibly explain this entirely without writing a book so I didn't go into things like scope, access modifiers, static, etc., but I tried to cover what I think is important to understand what you're asking. Like I said, I have no formal education so take my answer for what its worth but hopefully I was able to make it a little easier to understand.
Oh I forgot about your other question. A location in memory to store an object is declared when a variable for the object is created. At that point there is a location but the size in memory is still 0 or null because there is no object. The memory necessary to actually store the object will be filled when the object is instantiated.
Say I have classes
class A{
//code for class A
}
class B{
//code for class B
}
class A{
public static void main(String a[]){
//Initialize m instances of A and n instances of B and store each in arrays
//Equate any arbit index in the array to null
}
}
In this scenario, my main goal is to find all active instances of classes A and B in the memory at any point.
I suppose it must be possible using a debugger.
However, due to some reason (the reason being beyond the scope of the question), I am required to get the instances from within the code itself. Thus, i need a function like
public void getAllActiveInstances(){
//Print values
}
Edit: I don't need instances to operate over them. I just need to know whether they exist or not. This is mainly for debugging purposes.
If this is not possible then kindly explain how to do the same using debuggers.
The short answer is no, you should not be looking inside of memory at any time with java.
The long answer is, if there was any way of accessing an object after GC has collected it, then you are violating the GC's principal of only collecting things that cannot be reached in any way by the executing code. Garbage collected memory is freed and returned to the program to do anything it wants with it. This means if you've GC'd an object A, java is allowed to write any number of things into that location, destroying the "A-ness" of that block of memory. Attempting to read an object B that is now stored in that memory block and pretending it's an A will cause all sorts of problems.
Going forward: To keep track of all the classes you've created, I would suggest modifying the class itself. Your class can have a static container (like a HashMap), and the constructor adds the constructed class to the HashMap. However, note that because you are hanging onto references to all of your created object, Garbage collect will never collect those objects and free up that memory.
"In this scenario, my main goal is to find all active instances of classes A and B in the memory at any point irrespective of the Garbage Collector having deleted the object or not."
If the garbage collector has deleted it, it won't be an active instance, or indeed any kind of instance.
There is no Java API for this, sure JRockit Flight Control and/or a debugger could do this for you, but if you want an actual programmatic way of doing it, you'll have to hand-roll it. Good luck with making that reliable. You'll probably need to use Constructors and Finalizers to increase and decrease your object count.
Don't try and implement your own object pools unless you really, really think you can beat the hotspot optimiser at its own game.
As you mentioned you can do it using debugger. Java provides debugging API. You can kind of implement your own debugger and connect to the application itself.
Other way is to instrument your classes. I know the following techniques:
Instantiate them using special factory that stores references to all instances that have to be monitored.
Use AOP (e.g. AspectJ). The aspect will register created instances into repository (as described above)
Use java instrumentation package to change class on the fly. Take a look on SizeOf - a very simple project that uses java instrumentation API. You can use it as an example to learn the issue.
I have constructed a tiny custom class loader in a dummy application in order to understand how dynamic class loading works. For this question, I don't need to go into details about what it does other than to mention that it instantiates two different instances of my class loader and has each one load different classes, in order that I can satisfy myself by confirming a "ClassNotFoundException" from one of the class loader instances when only the other has loaded a particular class.
However, I have a question that can be easily expressed by the following, hopefully self-explanatory line of code.
Class clazz = myClassLoader.loadClass(theClazz);
This line of code causes my custom class loader to LOAD the class bytes into memory, and to return an instance of a Class object for that class.
My question is this: Where are the physical bytes of memory for the loaded class located (i.e., the contents of the .class file)? Are they stored inside the ClassLoader object, or are they stored inside the Class object (whereupon the ClassLoader object merely contains an internal reference to this Class object) - or somewhere else entirely?
The classloader object has a Collection of all classes it has loaded.
If the same physical class is loaded by 2 different class laoders, the bytes of that class are two times in memeory. The two classes behave like different types. They are not compatible to each other! Where the bytes are stored is not really relevant, I wonder why you want to know that. If you write your own ClassLoader you can "store" them where ever you want. However at some point you will make a call like: ClassLoader.defineClass(String, byte[], int, int). Then the relevant structures in memory inside the VM are created (MethodArea, ConstantPool etc.) as mentioned in other answers.
From the source code for ClassLoader:
// The classes loaded by this class loader. The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private Vector classes = new Vector();
The source code for the java classes are located in src.zip in your JDK directory.
Edit:
Was that what you asked about?
At the lowest level, the binary representation of the class is present in various runtime areas of the virtual machine, most notably in the Method Area and in the Runtime Constant Pool. In simpler terms, the Method Area is expected to contain information about the class, including the code for methods and constructors as evidenced by the following quote from the Virtual Machine Specification:
The Java virtual machine has a method
area that is shared among all Java
virtual machine threads. The method
area is analogous to the storage area
for compiled code of a conventional
language or analogous to the "text"
segment in a UNIX process. It stores
per-class structures such as the
runtime constant pool, field and
method data, and the code for methods
and constructors, including the
special methods (ยง3.9) used in class
and instance initialization and
interface type initialization.
"This line of code causes my custom class loader to LOAD the class bytes into memory, and to return an instance of a Class object for that class"
If I understand your question correct, memory allocation for objects is done on the heap space of the java process.
It depends on the JVM, seen for example here or here. Old versions of Mac OS used a pointer to pointer scheme, called a handle.
The class file and its internal, JVM-specific, representation are usually stored in the Permanent Generation - at least in the Sun/Oracle incarnation of the JVM.
See What does PermGen actually stand for? for more links.