Java 一个简单程序的类加载流程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20796046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 04:23:39  来源:igfitidea点击:

Flow of class loading for a simple program

javaclassloader

提问by Aarish Ramesh

I am just now beginning to learn the internal architecture of Java. I have roughly understood the concept of class loading which loads the required classes when jvmruns, ClassNotFoundExceptionis thrown when a class is not found and specific class loader loads the classes referenced by the class.

我现在才开始学习Java的内部架构。我大致理解了类加载的概念,jvm运行时加载所需的类,ClassNotFoundException找不到类时抛出,特定的类加载器加载类引用的类。

Can someone please explain clearly the flow of class loading i.e. the sequence of bootstrap class loading and user-defined class loading in the sample Java code below.

有人可以在下面的示例Java代码中清楚地解释类加载的流程,即引导类加载和用户定义类加载的顺序。

import java.io.File;
public class Sample
{
    public static void main(String[] args)
    {
        String fileName = "sample";
        File file = new File(fileName);
        file.isFile();
    }
} 

Also I learnt from a reference material that "classloadermaintains the namespaces of the classes it loads". By namespaces, does that mean the literal names of the class? Also can someone please explain the implication/advantage of that?

我还从“classloader维护它加载的类的命名空间”的参考资料中了解到。命名空间是指类的字面名称吗?也有人可以解释一下它的含义/优点吗?

采纳答案by Santosh

You will run your Sampleclass as follows

您将按Sample如下方式运行您的课程

> java Sample

> java Sample

for little magic, check out the output of-verbose:classoption and you see tons of following lines..

对于小魔法,检查-verbose:class选项的输出,你会看到大量的以下几行..

[Opened C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar]
.
.
.
.
.
.
[Loaded java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Sample from file:/D:/tmp/]
[Loaded java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar]

You see a bunch of classes from \jre\lib\rt.jarare loaded, much before your class is loaded by Bootstrapclass loader (or Primordial ). These are the pre-requisite for running any Java program hence loaded by Bootstrap.

您会看到\jre\lib\rt.jar加载了一堆类,远在类加载Bootstrap器(或 Primordial )加载您的类之前。这些是运行任何由 Bootstrap 加载的 Java 程序的先决条件。

Another set of jars is loaded by Extensionclass loader. In this particular example, there was no need of any classes from the lib \jre\lib\exthence its not loaded. But Extension class loader are specifically assigned the task of loading the classes from the extension lib.

另一组 jars 由Extension类加载器加载。在这个特定的例子中,不需要来自 lib 的任何类,\jre\lib\ext因此它没有加载。但是扩展类加载器被专门分配了从扩展库加载类的任务。

EDIT:Apart from the standard platform java classes Sun/Oracle also provide a set of jars which are used to extend the platform's core API. The jars placed in the extension lib folder are automatically placed in the classpath and hence not needed to be included in classpath explicitly. Here is nice official articleon the same topic.

编辑:除了标准平台 java 类之外,Sun/Oracle 还提供了一组用于扩展平台核心 API的 jar 。放置在扩展 lib 文件夹中的 jar 会自动放置在类路径中,因此不需要明确包含在类路径中。这是关于同一主题的不错的官方文章

Finally, your class Sampleis loaded by Applicationclass loader after Bootstrap and Extension have finished loading.

最后,在 Bootstrap 和 Extension 加载完成后SampleApplication类加载器会加载您的类。

回答by Aniket Thakur

JVM maintains a runtime pool in permgen area where classes are loaded. Whenever a class is referenced default class loader finds the class in the class path and loads it into this pool. And this is not specific to user defined classes or classes provided in JDK. When a class is referenced it is loaded into the memory.

JVM 在加载类的 permgen 区域维护一个运行时池。每当引用一个类时,默认类加载器都会在类路径中找到该类并将其加载到此池中。这不是特定于用户定义的类或 JDK 中提供的类。当一个类被引用时,它被加载到内存中。

Classes loaded by the ClassLoader are stored internally in the ClassLoader instance

ClassLoader 加载的类内部存储在 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 final Vector<Class<?>> classes = new Vector<>();

When class needs to be added to the memory following function is called:

当需要将类添加到内存中时,调用以下函数:

// Invoked by the VM to record every loaded class with this loader.
void addClass(Class c) {
    classes.addElement(c);
}

Found a useful diagram on how Class Loaders work.

找到了一个关于类加载器如何工作的有用图表。

enter image description here

在此处输入图片说明

回答by Narendra Pathai

Classloader hierarchy

类加载器层次结构

Whenever a new JVM is started the bootstrap classloader is responsible to load key Java classes (from java.langpackage) and other runtime classes to the memory first. The bootstrap classloader is a parent of all other classloaders. Consequently, it is the only one without a parent.

每当启动新的 JVM 时,引导类加载器负责首先将关键 Java 类(从java.lang包)和其他运行时类加载到内存中。引导类加载器是所有其他类加载器的父类。因此,它是唯一没有父母的。

Next comes the extension classloader. It has the bootstrap classloader as parent and is responsible for loading classes from all .jarfiles kept in the java.ext.dirspath–these are available regardless of the JVM's classpath.

接下来是扩展类加载器。它有引导类加载器作为父类,并负责从.jar保存在java.ext.dirs路径中的所有文件加载类——无论 JVM 的类路径如何,这些文件都是可用的。

The third and most important classloader from a developer's perspectiveis the system classpath classloader, which is an immediate child of the extension classloader. It loads classes from directories and jar files specified by the CLASSPATHenvironment variable, java.class.pathsystem property or -classpathcommand line option.

开发人员的角度来看,第三个也是最重要的类加载器是系统类路径类加载器,它是扩展类加载器的直接子代。它从由CLASSPATH环境变量、java.class.path系统属性或-classpath命令行选项指定的目录和 jar 文件加载类。

Classloader hierarchy

类加载器层次结构

ClassLoader Namespace

类加载器命名空间

In Java a class is uniquely identified using ClassLoader + Classas the same class may be loaded by two different class loaders.

在 Java 中,一个类是唯一标识的, ClassLoader + Class因为同一个类可以由两个不同的类加载器加载。

Class A loaded by ClassLoader A != Class A loaded by ClassLoader B

How is it helpful?

它有什么帮助?

It is helpful for defining different protection and access policies for different classloaders. Take an example of applet which is loaded using a different classloader, you would not want a third party application all access to your resources. So for security its important to maintain different namespaces.

它有助于为不同的类加载器定义不同的保护和访问策略。以使用不同类加载器加载的小程序为例,您不希望第三方应用程序可以访问您的资源。因此,为了安全起见,维护不同的命名空间很重要。

回答by rachana

The Java Virtual Machinestarts up by creating an initial class, which is specified in an implementation-dependent manner, using the bootstrap class loader (§5.3.1). The Java Virtual Machine then links the initial class, initializes it and the static instance variables declared in it and finally invokes the public class method void main(String[]). The invocation of this method drives all further execution. Execution of the Java Virtual Machine instructions constituting the main method may cause linking (and consequently creation) of additional classes and interfaces, as well as invocation of additional methods.

Java虚拟机通过创建一个初始类,这是在一种实现依赖性方式的规定,使用引导类加载器(启动§5.3.1)。Java 虚拟机然后链接初始类,初始化它和在其中声明的静态实例变量,最后调用公共类方法 void main(String[])。调用此方法会驱动所有进一步的执行。执行构成 main 方法的 Java 虚拟机指令可能会导致链接(并因此创建)附加类和接口,以及调用附加方法。

read thislink

阅读链接

回答by Nirmal

The loading process can be viewed as interaction between Classloader Subsystem and the Memory Area of JVM.

加载过程可以看作是 Classloader 子系统和 JVM 内存区之间的交互。

Classloader works in three general steps 1.) Loading 2.) Linking and 3.) Initialization.

类加载器分三个一般步骤工作:1.) 加载 2.) 链接和 3.) 初始化。

The very basic interaction between Classloader Subsystem and the Memory Area happens during Linking(apart from other interactions!)

类加载器子系统和内存区域之间非常基本的交互发生在链接期间(除了其他交互!)

Linking activity is subdivided into i.) Verify ii.) Prepare and iii.) Resolve. Verify: is more for security, valid compilation is checked. In the step ii.) Prepare - static variable memory is allocated and assigned with default values. And in

链接活动细分为 i.) 验证 ii.) 准备和 iii.) 解决。验证:更多是为了安全,检查有效编译。在步骤 ii.) 准备 - 分配静态变量内存并为其分配默认值。而在

iii.) Resolve: Symbolic references are replaced with original references from the "Method Area" which contains class level data and static variables.

iii.) 解决:符号引用被替换为来自“方法区”的原始引用,其中包含类级数据和静态变量。

JVM Arch

JVM 架构