JVM如何开始寻找类?

时间:2012-01-19 23:13:40

标签: java jvm classloader

  • 我很好奇JVM查找执行程序的所有位置?我更感兴趣的是了解JVM查找类文件的顺序和位置,比如查看java库,扩展库,类路径等任何目录,比如调用java的当前目录?我对JVM行为更感兴趣,而不是类加载器加载类的方式,我知道它有直到root的父委托机制。

  • 如果一个类是从编译类保存在文件系统上的目录中执行的,也是在同一目录下的一个jar文件中执行的,那么JVM是加载两个还是只加载哪一个?

  • 假设您有一个不安全的帖子Vector,如果我们将其效果与ArrayList进行比较,哪一个更好,为什么?

5 个答案:

答案 0 :(得分:7)

如何找到课程。 答案在这里:

http://docs.oracle.com/javase/1.5.0/docs/tooldocs/findingclasses.html

第2点的答案: 查找课程的顺序如下:

  1. 当前目录中的类或包。
  2. 从CLASSPATH环境变量中找到的类。 [覆盖1]
  3. 从-classpath命令行选项中找到的类。 [覆盖1,2]
  4. 通过-jar命令行选项指定的jar档案中找到的类[覆盖1,2,3]
  5. 因此,如果在运行时使用-jar选项,则类来自jarfile。

    虽然只加载了一个类。

答案 1 :(得分:7)

不使用任何其他类加载器:

  • JVM的搜索顺序:
    1. 运行时类(基本上是rt.jar中的$JRE_HOME/lib
    2. 扩展类($JRE_HOME/lib/ext中的一些JAR)
    3. Classpath,按顺序。指定类路径有四种可能性:
      1. 如果指定了-jar,则该JAR位于类路径中。在META-INF/MANIFEST.MF中声明为classpath的任何类路径也被视为。
      2. 否则,如果指定了-cp,那就是类路径。
      3. 否则,如果设置了$CLASSPATH,那就是类路径。
      4. 否则,java已启动的当前目录是类路径。
      5. 因此,如果我指定-cp src/A.jar:src/B.jar,则会先搜索A.jar,然后B.jar
      6. JVM根据在类路径中声明目录/ JAR的顺序,仅加载首先找到的类。如果您使用-cp$CLASSPATH
      7. ,这一点很重要
      8. 在单线程场景和最近的JVM中,VectorArrayList应该具有相似的性能(ArrayList应该稍微好一点,因为它不是synchronized,但锁定是当前没有争用的时候很快,所以差别应该很小)。无论如何,Vector已经过时:不要在新代码中使用它。

答案 2 :(得分:1)

  1. 我相信Java会根据“-cp”VM参数查找当前目录,然后是类路径。您可以放置​​任何类的文件夹组合(例如/ project / bin / com / putable),特定的类文件(例如/project/bin/com/putable/MyClass.class)和JAR文件(例如/ project / lib /) MyJar.jar)在类路径上。位置由冒号(基于Unix的操作系统)或分号(基于Windows的操作系统)分隔。因此,类路径上的任何内容都是Java在获取类定义时要考虑的公平游戏。关于序列,类是懒惰加载的。因此,只有在您的应用程序首次需要时才会加载它们。如果您的应用程序在其运行时期间不需要某个类,那么该类将永远不会被加载。

  2. 如果你没有在类路径上放任何东西,我认为Java将从类文件而不是Jar加载。如果在类路径中指定了一个或另一个,那么这就是Java将要查找的位置。如果你把两者放在类路径上,Java的类加载行为是未定义的,它可以选择,这取决于JVM的实现。

  3. 取决于您想要做什么。根据Java API,向量实际上始终是线程安全的,因此如果您不需要并发访问,则ArrayList会更快。向量和数组列表都由数组支持,但它们以不同的速率增加容量(每当达到结束时,向量容量加倍并且需要更多空间,但ArrayList增加50%)。根据您增长或缩小的频率,答案会有所不同。有关详细信息,请查看此链接:

  4. http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html

答案 3 :(得分:1)

  

我对JVM行为更感兴趣,而不是类加载器的加载方式   类

抱歉,这是荒谬的。 因为答案是JVM创建了一个类加载器,让这个类加载器加载类。 因此,为了理解“JVM行为”,您需要了解类加载器的行为。

但也许你的问题是:JVM如何创建系统类加载器?

答案 4 :(得分:0)

接受的答案已经是正确的,但是How Classes are Found中有更详细和更新的官方规范。

一些警告:

  

类文件具有一个子路径名称,该子路径名称反映了该类的完全限定名称。例如,如果com.mypackage.MyClass类存储在/ myclasses下,则/ myclasses必须在用户类路径中,并且类文件的完整路径必须在/myclasses/com/mypackage/MyClass.class中。如果该类存储在名为myclasses.jar的存档中,则myclasses.jar必须位于用户类路径中,并且该类文件必须作为com / mypackage / MyClass.class存储在存档中。

以及 Java启动器如何查找用户类

中的优先级
  
      
  • 默认值“。”,表示用户类文件是当前目录中的所有类文件(如果在包中,则位于其下)。
  •   
  • CLASSPATH环境变量的值,它将覆盖默认值。
  •   
  • -cp或-classpath命令行选项的值,它将覆盖默认值和CLASSPATH值。
  •   
  • -jar选项指定的JAR归档文件,它将覆盖所有其他值。如果使用此选项,则所有用户类都必须出现
      来自指定的存档。
  •