最近,我在我的web应用程序中遇到了这个错误:

java.lang.OutOfMemoryError:永久生成空间

它是一个典型的Hibernate/JPA + IceFaces/JSF应用程序,运行在Tomcat 6和JDK 1.6上。 显然,这可能发生在重新部署应用程序几次之后。

是什么原因导致的,如何避免呢? 我该如何解决这个问题?


当前回答

由于使用了较大的空间而不是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,这个问题就不会发生。

其他回答

尝试-XX:MaxPermSize=256m,如果仍然存在,尝试-XX:MaxPermSize=512m

对我来说,唯一有效的方法就是JRockit JVM。我有MyEclipse 8.6。

JVM的堆存储运行中的Java程序生成的所有对象。Java使用new操作符创建对象,并且在运行时在堆上为新对象分配内存。垃圾收集是一种自动释放程序不再引用的对象所包含的内存的机制。

从Tomcat的bin目录打开tomcat7w,或者在开始菜单中键入Monitor Tomcat (打开一个带有各种服务信息的选项卡窗口)。 在Java Options文本区域中添加这一行: - xx: MaxPermSize = 128 “初始内存池”设置为“1024”(可选)。 “最大内存池”设置为“1024”(可选)。 单击Ok。 重启Tomcat服务。

我也有类似的问题。 我的是基于JDK 7 + Maven 3.0.2 + Struts 2.0 +谷歌GUICE依赖注入的项目。

当我尝试运行mvn清洁包命令时,它显示以下错误和“BUILD FAILURE”发生

org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException;java.lang.reflect.InvocationTargetException: null java.lang.reflect.InvocationTargetException 由:java.lang.OutOfMemoryError: PermGen space引起

我尝试了上面所有有用的技巧,但不幸的是,没有一个对我有效。 对我有效的方法如下:=>

转到pom.xml 搜索<artifactId>maven-surefire-plugin</artifactId> 添加一个新的<configuration>元素和<argLine>子元素,其中pass -Xmx512m -XX:MaxPermSize=256m,如下所示=>

< configuration > < argLine > -Xmx512m -XX: MaxPermSize = 256m < / argLine > < / configuration >

希望能有所帮助,编程愉快:)

为Tomcat分配更多内存不是正确的解决方案。

正确的解决方案是在销毁和重新创建上下文(热部署)之后进行清理。解决方案是停止内存泄漏。

如果Tomcat/Webapp服务器告诉您未能注销驱动程序(JDBC),那么请注销它们。这将阻止内存泄漏。

您可以创建一个ServletContextListener并在web.xml中配置它。下面是一个示例ServletContextListener:

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;

import com.mysql.jdbc.AbandonedConnectionCleanupThread;

/**
 * 
 * @author alejandro.tkachuk / calculistik.com
 *
 */
public class AppContextListener implements ServletContextListener {

    private static final Logger logger = Logger.getLogger(AppContextListener.class);

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        logger.info("AppContextListener started");
    }

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        logger.info("AppContextListener destroyed");

        // manually unregister the JDBC drivers
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                logger.info(String.format("Unregistering jdbc driver: %s", driver));
            } catch (SQLException e) {
                logger.info(String.format("Error unregistering driver %s", driver), e);
            }

        }

        // manually shutdown clean up threads
        try {
            AbandonedConnectionCleanupThread.shutdown();
            logger.info("Shutting down AbandonedConnectionCleanupThread");
        } catch (InterruptedException e) {
            logger.warn("SEVERE problem shutting down AbandonedConnectionCleanupThread: ", e);
            e.printStackTrace();
        }        
    }
}

然后在web.xml中进行配置:

<listener>
    <listener-class>
        com.calculistik.mediweb.context.AppContextListener 
    </listener-class>
</listener>