简体   繁体   中英

Java: Where is the memory allocated for the physical bytes of a class when loaded by a ClassLoader?

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 (ie, 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?

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM