JVM如何开始寻找类?

问题描述 投票:10回答:5
  • 我很好奇JVM查找执行程序的所有位置?我更感兴趣的是了解JVM查找类文件的顺序和位置,比如查看java库,扩展库,类路径等任何目录,比如调用java的当前目录?我对JVM行为更感兴趣,而不是类加载器加载类的方式,我知道它有直到root的父委托机制。
  • 如果从编译类保存在文件系统上的目录以及同一目录中的jar文件中执行类,那么JVM是加载两个还是只加载一个?
  • 假设你有一个线程不安全Vector,如果我们将它的性能与ArrayList进行比较,哪一个会更好,为什么?
java jvm classloader
5个回答
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]

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

但是只加载了一个类。


7
投票

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

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

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%)。根据您增长或缩小的频率,答案会有所不同。查看此链接以获取更多信息:

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


1
投票

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

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

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


0
投票

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

一些警告如下:

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

以及Java Launcher如何查找用户类的优先级

  • 默认值“。”,表示用户类文件是当前目录中的所有类文件(如果在包中,则位于其下)。
  • CLASSPATH环境变量的值,它覆盖默认值。
  • -cp或-classpath命令行选项的值,它会覆盖缺省值和CLASSPATH值。
  • 由-jar选项指定的JAR存档,它覆盖所有其他值。如果使用此选项,则必须使用所有用户类 来自指定的档案。
© www.soinside.com 2019 - 2024. All rights reserved.