Java jar中的类何时进入PermGen

Java jar中的类何时进入PermGen,java,tomcat,classpath,classloader,permgen,Java,Tomcat,Classpath,Classloader,Permgen,我的理解是PermGen(在某种意义上)将类代码保存在内存中。我们经常有很多jar文件引用我们的类路径。当一个jar文件包含在类路径中(比如tomcat的lib目录中)时,所有这些jar的所有类都会自动加载到PermGen中吗 在一个类似的问题中,一旦使用了jar文件的一个类,PermGen是加载该jar文件中的所有类,还是只加载所使用的类(然后在必要时加载其余的类文件)?只有需要的类才会加载并存储在permgen空间中。保证类在第一次需要时初始化,并且不早于第一次需要时初始化。但是,允许实现更

我的理解是PermGen(在某种意义上)将类代码保存在内存中。我们经常有很多jar文件引用我们的类路径。当一个jar文件包含在类路径中(比如tomcat的lib目录中)时,所有这些jar的所有类都会自动加载到PermGen中吗


在一个类似的问题中,一旦使用了jar文件的一个类,PermGen是加载该jar文件中的所有类,还是只加载所使用的类(然后在必要时加载其余的类文件)?

只有需要的类才会加载并存储在permgen空间中。

保证类在第一次需要时初始化,并且不早于第一次需要时初始化。但是,允许实现更早地执行加载和链接。

这在某种程度上取决于类加载器和JVM的实现-声明如下:

该规范允许在何时实现灵活性 链接活动(由于递归,加载)发生, 前提是Java编程语言的语义是 尊敬的,[……]

例如,一个实现可以选择解析每个符号 仅在使用类或接口时,才单独在类或接口中引用 (懒散或延迟解决),或在 正在验证类(静态分辨率)。这意味着 在某些实现中,解决过程可能会在 类或接口已初始化


实际上,没有一个健全的实现应该仅仅因为加载了JAR文件中的一个类就自动加载该文件中的所有内容,更不用说仅仅因为它位于类路径上了

PermGen是HotSpot的一个实现细节,Oracle表示他们希望在将来摆脱它[1]。它不在Java(VM)规范中。只有加载的类才会在PermGen中结束。可以通过
ClassLoader#loadClass
显式地,也可以通过链接隐式地。除非有人显式加载所有类(例如,对它们执行反射),否则应该只使用这些类(及其依赖项)。像Spring这样的框架避免了这种情况,而是扫描字节码

一个很好的起点是,允许您通过PermGen观察加载的类


[1] JRockit没有PermGen,在最近的热点版本中,字符串intern池不再位于PermGen中。

实际上,规范明确允许预加载类。一个类在被使用之前必须被加载是很明显的。那么初始化它们呢?那是另一回事。我认为初始化与PermGen的使用无关,尽管我认为实现可能会延迟加载相关类,直到初始化。值得注意的是,只有java.lang.Class对象,一些与类名称和方法名称相关的java.lang.String对象,类引用的静态对象将加载到PermGen中。它不像你的字节码被加载在那里或其他任何东西。。。