java.lang.OutOfMemoryError:PermGen空间

时间:2010-09-18 23:58:52

标签: java eclipse memory jvm initialization

我在eclipse IDE 3.2中经常出现以下错误,如何从这些OutOfMemory中保存应用程序?

java.lang.OutOfMemoryError: PermGen space
    java.lang.ClassLoader.defineClass1(Native Method)
    java.lang.ClassLoader.defineClassCond(Unknown Source)
    java.lang.ClassLoader.defineClass(Unknown Source)
    java.security.SecureClassLoader.defineClass(Unknown Source)
    org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1814)
    org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872)
    org.jboss.web.tomcat.service.WebAppClassLoader.findClass(WebAppClassLoader.java:75)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1325)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
    com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:289)
    java.sql.DriverManager.getConnection(Unknown Source)
    java.sql.DriverManager.getConnection(Unknown Source)
    org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133)
    org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:111)
    org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2101)
    org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1325)
    com.mfic.util.HibernateUtil.<clinit>(HibernateUtil.java:16)
    com.mfic.dao.BaseHome.getSession(BaseHome.java:16)
    com.mfic.core.helper.UserManager.findByUserId(UserManager.java:248)
    com.mfic.core.action.Login.authenticate(Login.java:39)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:280)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:243)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:165)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:252)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)

8 个答案:

答案 0 :(得分:36)

如果您在辅助Eclipse应用程序中收到疑问错误,则在-XX:MaxPermSize=512m中添加ini将无济于事。您需要进入debug or run configuration->arguments并在VM参数中添加该部分。我还增加了其他内存限制:

-Dosgi.requiredJavaVersion=1.5 -Xms120m -Xmx2048m -XX:MaxPermSize=1024m

它有所帮助。

编辑。经过一些实验,我发现Eclipse确实从ini文件中获取了内存限制。但是......它只创建了一个新的工作区。 eclipse.ini中-vmarg的参数创建默认的VM参数行。因此,如果您正在处理现有工作区,请更改调试或运行配置。但是也要改变eclipse.ini,以获得更好的未来。

答案 1 :(得分:20)

您的项目占用了大量内存。为Eclipse提供更多内存。修改eclipse.ini以修改或添加-vmargs下面的以下行。

-Xms256m
-Xmx512m
-XX:MaxPermSize=512m

假设你至少有2GB的RAM。

另见:

答案 2 :(得分:18)

  • 单击“服务器实例”。
  • 打开启动配置。
  • 在参数选项卡中将内存增加到JVM。

-Xms64m -Xmx256m

见下图:

enter image description here

答案 3 :(得分:5)

允许Java应用程序仅使用有限数量的内存。在应用程序启动期间指定特定应用程序可以使用的确切内存量。为了使事情变得更复杂,Java内存被分成不同的区域,其中一个区域被称为PermGen。

在JVM启动期间设置所有这些区域的大小。如果未明确设置大小,将使用特定于平台的默认值。

所以 - java.lang.OutOfMemoryError: PermGen space消息表明内存中的永久大小区域已耗尽

这个名为PemGen的特定区域是一个加载和存储Java类的专用区域。这包括以下内容:

  • 班级名称
  • 班级的字段
  • 具有方法字节码的类的方法
  • 常量池信息
  • 与类
  • 关联的对象数组和类型数组
  • Just In Time编译器优化

这就是它。更多的点点滴滴,但它不会影响实际内存消耗超过百分之几。所有这些都分配给了永久性的一代,并留在了永久的一代。

如您所见,永久生成大小要求取决于加载的类的数量以及此类声明的大小。因此很容易看出导致此类错误的主要原因:太多类或太大的类被加载到永久代

症状的快速修复很容易 - 如果我们已经耗尽了堆中的PermGen区域,我们需要增加它的大小。如果没有给你的JVM足够的肘部空间,这个解决方案确实很有帮助。因此,请更改应用程序启动配置并添加(或增加(如果存在)以下内容:

-XX:MaxPermSize=512m

答案 4 :(得分:2)

在调试会话期间在Eclipse中运行Tomcat时,这种情况经常发生。从内存来看,这是Sun JVM的一个问题。 Annnyway,有一个简单的解决方法:

只需在eclipse.ini中的-vmargs下面添加以下内容(与eclipse二进制文件位于同一目录中):

-XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-XX:+CMSPermGenSweepingEnabled 

这将在运行Eclipse时实现更积极的垃圾收集,并且是比在Eclipse中投入更多RAM更优雅的解决方案。

希望这有帮助!

答案 5 :(得分:2)

上面的答案可能会为你解决,但无论如何这里有一些有趣的相关链接:

这篇文章有很多关于此错误的讨论和建议: http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang

讨论如何发生Permgen OOM错误的示例: http://blogs.oracle.com/fkieviet/entry/classloader_leaks_the_dreaded_java

这是最近发布在StackOverflow上的实际解决方案。 它适用于Tomcat,但可以在Eclipse中使用: Dealing with "java.lang.OutOfMemoryError: PermGen space" error

答案 6 :(得分:1)

增加MaxPermSize中的eclipse.ini。如果你很舒服,我建议把它设置为128M或256M

-vmargs -XX:PermSize=64M -XX:MaxPermSize=128M  

另请注意,很多人在Perm-Gen Errors Got You Down?中报告了Eclipse 3.2的PermGen问题。由于Eclipse 3.2已有4年多的历史,我建议升级到更新的版本(Eclipse 3.6是当前版本)。

参考

答案 7 :(得分:1)

在尝试上述选项后,请查看更新的JVM。 我正在使用jdk1.6并面临同样的问题。 当我将eclipse中的jvm更改为JDK1.7时,它工作正常。