出现问题的运行环境: JDK 1.7,Tomcat 7
Tomcat 运行的时候,或热部署时偶尔会出现 java.lang.OutOfMemoryError: PermGen space 的错误。PermGen 指 Permanent Generation,是 Java 内存划分的一个区域,包含了类相关的信息,包括字节码、名字和JIT等信息。
出错原因
有太多的类或太大的类被加载到 permanent generation 中
解决方法:
JVM 命令行增加选项:
-XX:MaxPermSize=512m
MaxPermSize 的大小视情况而定
另一种方法
-XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
参考
Dealing with “java.lang.OutOfMemoryError: PermGen space” error
java.lang.OutOfMemoryError: Permgen space
Java 8 中的 PermGen
Java 8将 PermGen 从 HotSpot JVM 中移除,其中的某些部分,如被 intern 的字符串,在Java 7中已经移到了普通堆里。其余结构在Java 8中会被移到称作“Metaspace”的本机内存区中,该区域在默认情况下会自动生长,也会被垃圾回收。它有两个标记:MetaspaceSize 和 MaxMetaspaceSize。
引用某相关人员的解释:
移除了PermGen,用户就无需考虑如何正确设置其大小了,这是我们的一个目标。
如果知道应用程序的类数据需要更多空间,可以把MetaspaceSize设置的比默认值大些。 这能减少一些启动时的GC次数。不过没必要这么做。除非你想尽量减少GC次数,否则我不建议这么做。
如果想限制类数据所占空间的大小,可以设置MaxMetaspaceSize。如果怀疑出现类加载器泄漏,并且希望应用在耗尽太多本机内存前停止,应该设置它。还有一种使用场合,那就是在一个服务器上运行了多个应用,而且用户希望限制每个应用所占的类空间大小。