最近,我在我的web应用程序中遇到了这个错误:
java.lang.OutOfMemoryError:永久生成空间
它是一个典型的Hibernate/JPA + IceFaces/JSF应用程序,运行在Tomcat 6和JDK 1.6上。 显然,这可能发生在重新部署应用程序几次之后。
是什么原因导致的,如何避免呢? 我该如何解决这个问题?
最近,我在我的web应用程序中遇到了这个错误:
java.lang.OutOfMemoryError:永久生成空间
它是一个典型的Hibernate/JPA + IceFaces/JSF应用程序,运行在Tomcat 6和JDK 1.6上。 显然,这可能发生在重新部署应用程序几次之后。
是什么原因导致的,如何避免呢? 我该如何解决这个问题?
当前回答
对我来说,唯一有效的方法就是JRockit JVM。我有MyEclipse 8.6。
JVM的堆存储运行中的Java程序生成的所有对象。Java使用new操作符创建对象,并且在运行时在堆上为新对象分配内存。垃圾收集是一种自动释放程序不再引用的对象所包含的内存的机制。
其他回答
In case you are getting this in the eclipse IDE, even after setting the parameters --launcher.XXMaxPermSize, -XX:MaxPermSize, etc, still if you are getting the same error, it most likely is that the eclipse is using a buggy version of JRE which would have been installed by some third party applications and set to default. These buggy versions do not pick up the PermSize parameters and so no matter whatever you set, you still keep getting these memory errors. So, in your eclipse.ini add the following parameters:
-vm <path to the right JRE directory>/<name of javaw executable>
还要确保将eclipse中的首选项中的默认JRE设置为正确的java版本。
由于使用了较大的空间而不是jvm提供的空间来执行代码,会发生Perm gen space错误。
在UNIX操作系统中,这个问题的最佳解决方案是更改bash文件上的一些配置。以下步骤可以解决该问题。
在终端上执行gedit .bashrc命令。
用以下值创建JAVA_OTPS变量:
export JAVA_OPTS="-XX:PermSize=256m -XX:MaxPermSize=512m"
保存bash文件。在终端上执行exec bash命令。重新启动服务器。
我希望这个方法能解决你的问题。如果您使用低于8的Java版本,有时会出现此问题。但是如果你使用Java 8,这个问题就不会发生。
Jrockit也帮我解决了这个问题;但是,我注意到servlet的重启时间要短得多,所以虽然在生产环境中效果更好,但在开发过程中却有点拖后腿。
1)增加永久内存大小
The first thing one can do is to make the size of the permanent generation heap space bigger. This cannot be done with the usual –Xms(set initial heap size) and –Xmx(set maximum heap size) JVM arguments, since as mentioned, the permanent generation heap space is entirely separate from the regular Java Heap space, and these arguments set the space for this regular Java heap space. However, there are similar arguments which can be used(at least with the Sun/OpenJDK jvms) to make the size of the permanent generation heap bigger:
-XX:MaxPermSize=128m
默认为64m。
2)启用扫地功能
另一种方法是允许类被卸载,这样你的PermGen就永远不会用完:
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
这种方法在过去对我很有效。不过,有一件事是,使用这些有一个显著的性能权衡,因为永久扫描将像额外的2个请求,你发出的每一个请求或类似的东西。您需要在使用和权衡之间取得平衡。
您可以找到这个错误的详细信息。
http://faisalbhagat.blogspot.com/2014/09/java-outofmemoryerror-permgen.html
解决方案是在启动Tomcat时将这些标志添加到JVM命令行:
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
您可以通过关闭tomcat服务,然后进入tomcat /bin目录并运行tomcat6w.exe来做到这一点。在“Java”选项卡下,将参数添加到“Java选项”框。单击“确定”,然后重新启动服务。
如果你得到一个错误,指定的服务不存在作为一个安装的服务,你应该运行:
tomcat6w //ES//servicename
其中servicename是在services.msc
来源:orx对Eric敏捷回答的评论。