【问题标题】:Why JVM first request Application ClassLoader to load a class when eventually this request is delegated to Bootstrap classloader?当最终这个请求被委托给 Bootstrap 类加载器时,为什么 JVM 首先请求 Application ClassLoader 加载一个类?
【发布时间】:2015-08-22 05:31:45
【问题描述】:

根据我的阅读,当 JVM 需要一个类时,会发生以下事件:

  1. 请求被发送到应用程序类加载器以加载类。
  2. 应用程序类加载器将请求委托给扩展类加载器。
  3. 扩展类加载器将请求委托给 Bootstrap 类加载器。
  4. Bootstrap 类加载器尝试从 Bootstrap 类路径加载类。如果在那里找到类,则加载它。
  5. 如果引导类路径中不存在类,则扩展类加载器会尝试从扩展类路径加载类。
  6. 如果类即使在扩展类路径中也不存在,则应用程序类加载器会尝试从应用程序类路径(即 CLASSPATH 环境变量路径)加载类。
  7. 如果类不存在,则抛出 ClassNotFoundException。

问题: 当每一个类加载请求最终都必须交给 Bootstrap 类加载器时,为什么 JVM 会先承担请求 Application Class loader 的开销,然后让它逐渐将请求委托给 Bootstrap 类加载器。 为什么不直接请求Bootstrap类加载器?

是否有任何具体原因,或者我缺少一些东西,我需要阅读更多内容?

【问题讨论】:

    标签: java class classloader classnotfoundexception


    【解决方案1】:

    类加载器有3个原则:

    1. 委托
    2. 可见性
    3. 独特性

    查看这篇文章:http://javarevisited.blogspot.co.id/2012/12/how-classloader-works-in-java.html

    关于可见性原则,Application 或 System 类加载器可以看到所有加载的类文件,但Bootstrap 或 Primordial 不能。

    作为 Application 类加载器是 Bootstrap 类加载器的子类

    为了保证一个类只被加载一次,从而保证唯一性,加载类的请求首先要发送到Application / System类加载器.

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      JVM 并不专门寻找应用程序级的类加载器。相反,当触发类 C 的类加载时(通过加载引用尚未加载的类的类 D,或通过类 D 的反射)而不指定类加载器,加载请求是指向D 的定义加载器,它通常是应用程序加载器。然后默认策略是委托给扩展和引导加载程序,但这种行为在技术上不是必需的。

      这样做的一个主要原因是,如果您有一些共享类型,则需要在使用它的所有协作类的某个祖先类加载器中定义它,因为类型在运行时通过它们的完整组合来标识名称和他们的装载机。 (OSGi 使用此规则将类的可见性限制在专门声明对它们的依赖关系的包中。)

      请注意,如果类D(比如java.net.URL)是由引导加载程序定义的,那么它加载的任何类C(比如java.lang.String)都会立即由引导加载程序加载。

      The JVM Specification's section on loading and linking 提供有关分辨率和加载过程的详细信息。

      【讨论】:

      • 正如您所说,“默认策略是委托给扩展和引导加载程序,但这种行为在技术上不是必需的”。这正是我的问题。保持这种行为背后的思考过程是什么?
      • @GauravKumar 我正在更新,我想我现在回答了。基本上,您希望类型由最高公共祖先类加载器定义,以便所有子加载器共享它们。
      • 你能提供一个例子来解释你在这里想说什么。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-01
      • 1970-01-01
      • 2011-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多