JVM如何开始寻找类?

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

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

  • 假设你有一个线程不安全的Vector ,如果我们将它的性能与ArrayList进行比较,哪一个会更好,为什么?

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

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]

因此,如果在运行时使用-jar选项,则类来自jarfile。

但是只加载了一个类。

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

  • JVM的搜索顺序:
    1. 运行时类(基本上是$JRE_HOME/lib rt.jar中的rt.jar
    2. 扩展类( $JRE_HOME/lib/ext一些JAR)
    3. 类路径,按顺序。 指定类路径有四种可能性:
      1. 如果指定了-jar ,那么该JAR位于类路径中。 无论在META-INF/MANIFEST.MF中将META-INF/MANIFEST.MF类路径声明为类路径,也要考虑。
      2. 否则,如果指定了-cp ,那就是类路径。
      3. 否则,如果设置了$CLASSPATH ,那就是类路径。
      4. 否则,启动java的当前目录是类路径。

      所以,如果我指定-cp src/A.jar:src/B.jar ,则A.jar搜索-cp src/A.jar:src/B.jar ,然后搜索B.jar

  • 根据在类路径中声明目录/ JAR的顺序,JVM仅加载首先找到的类。 如果使用-cp$CLASSPATH这很重要。
  • 在单线程场景和最近的JVM中, VectorArrayList应该具有相似的性能( ArrayList应该稍微好一点,因为它没有synchronized ,但是当没有争用时锁定很快,所以差异应该很小)。 无论如何, Vector已经过时了:不要在新代码中使用它。
  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将更快。 向量和ArrayLists都由数组支持,但它们以不同的速率增加容量(每当达到结束时,向量容量加倍并且需要更多空间,但ArrayList增加50%)。 根据您增长或缩小的频率,答案会有所不同。 查看此链接以获取更多信息:

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

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

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

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

首先,默认情况下,Java运行时系统使用当前工作目录作为起点。 因此,如果您的包位于当前目录的子目录中,则会找到它。 其次,您可以通过设置CLASSPATH环境变量来指定目录路径。 第三,您可以在java和javac中使用-classpath选项来指定类的路径。
例如,请考虑以下包规范:

包MyPack;

为了让程序找到MyPack,必须满足以下三个方面之一。 程序可以从MyPack上方的目录执行,或者CLASSPATH必须设置为包含MyPack的路径,或者-classpath选项必须指定程序通过java运行时MyPack的路径。 使用后两个选项时,类路径不得包含MyPack本身。 它必须简单地指定MyPack的路径。 例如,在Windows环境中,如果是MyPack的路径

C:\ MyPrograms \的Java \ MyPack

然后是MyPack的类路径

C:\ MyPrograms \ Java的

尝试显示示例的最简单方法是在当前开发目录下创建包目录,将.class文件放入相应的目录,然后从开发目录执行程序。 这是以下示例中使用的方法。