cppaddict said:
Let's say your have:
class MyClass {
int mOnlyMember;
public void method1() {
//a huge complex method body
}
}
(You've already had the simple answer, and on c.l.j.help I'd leave it at that,
but here....)
(Warning: all the following is simplified but, I hope, not over-simplified)
In this situation, once the class is loaded into the JVM you have:
The data-structure representing the class at runtime. This includes (but is
not limited to) the instance of java.lang.Class for MyClass. There is just one
of this. It will also have references to:
The data-structures representing the /definitions of/ the fields and methods at
runtime. These will include (but not be limited to) the corresponding
instances of java.lang.reflect.Method ...Field and ...Constructor. There will
be one of these for each member. The actual storage for holding the runtime
values of static variables is also in here somewhere.
If the JVM is not a simple interpreter, then the compiled code corresponding to
the bodies of the methods and constructors. Each will be, for instance, a
block of memory containing i86 binary code. (Actually these may not be created
until later, and they may be modified subsequently, or they may not be created
at all, but the simplification will do for now.)
All of the above are part of the runtime representation of a class (in a wide
sense). They are created when the class is loaded and will last until the JVM
exits or the class is garbage collected. They are shared amongst all of the
class's instances, but will exist (and take up space) even if the class is
never instantiated.
When you create an object, say a MyClass, storage will be allocated for that
object (as you know). That storage will contain, for /each/ object:
Space to hold its instance variables.
A pointer to (some part of) the runtime representation of the class. This is
needed so that the JVM can "find" the right methods to execute at runtime, and
so that it "knows" what class the object is. (Exactly /how/ it does these
things is a topic of active research, but I think that most, if not all,
production JVMs use an old-fashioned but reasonably simple and effective
technique called a "vtable" -- about which you can ask more or try Google if
you are interested). This pointer is the same for all instances of that class.
Space to hold any "housekeeping" information needed by the JVM. E.g. tags for
helping with garbage collection, some sort of support for the Java's
"synchronized" keyword, an indication of the size of the object, etc, etc...
This stuff (plus the pointer to the class) are often lumped together and called
the object's "header". Exactly what's in the header is completely
implementation dependent.
BTW (I presume you know this already but it seems to be a point that can cause
confusion, so I may as well state it here), the instance of MyClass will also
contain space for any instance variables that it inherits from its superclass.
It does /not/ contain a pointer to a separate "superclass object". In this
case, MyClass is a subclass of Object which doesn't have any variables so no
extra space is needed.
So:
When you create a new instance of MyClass, I know new memory is
allocated for mOnlyMember, but is new memory also allocated for
method1()? That is, does each object have it's own copy of the method?
More to the point, when I create a new instance of MyClass, is it
expensive (because the method body is so complex) or is it cheap
(because there's only a single int member)?
the answers are, respectively, "no", "no" and "cheap" ;-)
-- chris