Java:当类加载器加载类时,为类的物理字节分配的内存在哪里?
我在虚拟应用程序中构建了一个小型自定义类加载器,以便了解动态类加载的工作原理。对于这个问题,我不需要详细介绍它的作用,只是提到它实例化了我的类加载器的两个不同实例,并让每个实例加载不同的类,以便我可以通过确认“来满足自己”当只有另一个类加载器实例加载了特定类时,来自其中一个类加载器实例的 ClassNotFoundException”。
但是,我有一个问题可以通过以下希望不言自明的代码行轻松表达。
Class clazz = myClassLoader.loadClass(theClazz);
这行代码使我的自定义类加载器将类字节加载到内存中,并返回该类的 Class
对象的实例。
我的问题是:加载的类的物理内存字节位于哪里(即 .class 文件的内容)?它们是存储在 ClassLoader
对象中,还是存储在 Class
对象中(此时 ClassLoader 对象仅包含对此 Class
的内部引用)对象) - 或者完全在其他地方?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
类加载器对象有一个它已加载的所有类的集合。
如果同一个物理类被两个不同的类加载器加载,则该类的字节在内存中是两倍。这两个类的行为类似于不同的类型。他们彼此不兼容!字节存储在哪里并不真正相关,我想知道你为什么想知道这一点。如果您编写自己的类加载器,您可以将它们“存储”在您想要的任何位置。然而,在某些时候,您将进行如下调用:ClassLoader.defineClass(String, byte[], int, int)。然后,如其他答案中所述,创建 VM 内内存中的相关结构(MethodArea、ConstantPool 等)。
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.
来自 ClassLoader 的源代码:
java 类的源代码位于 JDK 目录中的 src.zip 中。
编辑:
你问的是这个吗?
From the source code for ClassLoader:
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:
如果我正确理解你的问题,对象的内存分配是在堆空间上完成的java进程。
If I understand your question correct, memory allocation for objects is done on the heap space of the java process.
它取决于 JVM,例如 此处 或此处< /a>.旧版本的 Mac OS 使用指针到指针的方案,称为句柄。
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.
类文件及其内部的、特定于 JVM 的表示通常存储在永久代中 - 至少在 JVM 的 Sun/Oracle 版本中是这样。
有关更多链接,请参阅PermGen 实际上代表什么?。
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.