什么时候罐子里的类进入PermGen

时间:2012-05-21 18:17:47

标签: java tomcat classpath classloader permgen

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

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

4 个答案:

答案 0 :(得分:4)

这在某种程度上取决于类加载器和JVM的实现 - Java Virtual Machine specification说明了这一点:

  

该规范允许实现灵活性   链接活动(并且,由于递归,加载)发生,   只要Java编程语言的语义是   尊重,[...]

     

例如,实现可以选择解析每个符号   仅在使用时才在类或接口中单独引用   (懒惰或迟到的解决方案),或者一次解决它们   正在验证类(静态分辨率)。这意味着   在一些实施方式中,在a之后,解析过程可以继续   类或接口已初始化。

实际上,没有理智的实现应该自动加载JAR文件中的所有内容,因为文件中的一个类被加载,更不用说只是因为它在类路径上了。

答案 1 :(得分:2)

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

一个很好的启发点是VisualVM,它允许你观察加载的类PermGen。

[1] JRockit没有PermGen,在最近的HotSpot版本中,字符串实习池不再是PermGen。

答案 2 :(得分:0)

只需要加载所需的类并将其存储在permgen空间中。

答案 3 :(得分:0)

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