Java堆空间溢出错误:Maven中的java.lang.OutOfMemoryError

146
运行maven test时,发生了java.lang.OutOfMemoryError错误。我在网上搜索了解决方法,并尝试使用“export MAVEN_OPTS=-Xmx1024m”来解决问题,但它没有起作用。 有人知道这个问题的其他解决方案吗?我正在使用maven 3.0。
运行“mvn test -e”命令后,将错误消息粘贴到此处:
测试失败: 警告(junit.framework.TestSuite$1) testDefaultPigJob_1(com.snda.dw.pig.impl.DefaultPigJobLocalTest) testDefaultPigJob_2(com.snda.dw.pig.impl.DefaultPigJobLocalTest)
运行的测试:11,失败:3,错误:0,跳过:0
10/11/01 13:37:18 INFO executionengine.HExecutionEngine: 正在连接到 hadoop 文件系统: file:/// [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] 总时间:30.063秒 [INFO] 完成时间:2010年11月1日星期一 下午1:37:18 PDT [INFO] 最终内存:3M/6M [INFO] ------------------------------------------------------------------------ [ERROR] 执行目标 org.apache.maven.plugins:maven-surefire-plugin:2.5:test (default-test) 失败,项目 dw.pig: 存在测试失败项。 [ERROR] [ERROR] 请参阅 E:\Code\Java\workspace\dw.pig\target\surefire-reports 获取单个测试结果。 [ERROR] -> [Help 1] org.apache.maven.lifecycle.LifecycleExecutionException: 在项目 dw.pig 上执行目标 org.apache.maven.plugins:maven-surefire-plugin:2.5:test(default-test) 失败: 存在测试失败项。
请参阅E:\Code\Java\workspace\dw.pig\target\surefire-reports以获取单个测试结果。 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:199) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:140) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59) at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:314) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:151) at org.apache.maven.cli.MavenCli.execute(MavenCli.java:445) at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:168) at org.apache.maven.cli.MavenCli.main(MavenCli.java:132) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290) at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409) at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352) Caused by: org.apache.maven.plugin.MojoFailureException: 在项目 dw.pig 上执行目标 org.apache.maven.plugins:maven-surefire-plugin:2.5:test (default-test) 失败: 存在测试失败项。
请参阅 E:\Code\Java\workspace\dw.pig\target\surefire-reports 获取单个测试结果。 at org.apache.maven.plugin.surefire.SurefirePlugin.execute(SurefirePlugin.java:629) at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:107) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:195) ... 19 more

1
也许你的测试中有内存泄漏问题?尽管Java有垃圾回收机制,但仍然可能导致内存泄漏:http://www.ibm.com/developerworks/library/j-leaks/ - anio
8个回答

179
当我运行maven test时,会出现java.lang.OutOfMemoryError错误。我通过谷歌寻找解决方案,并尝试导出MAVEN_OPTS=-Xmx1024m,但它没有起作用。使用MAVEN_OPTS设置Xmx选项是有效的,它确实配置了用于启动Maven的JVM。话虽如此,默认情况下,maven-surefire-plugin forks 一个新的JVM,因此您的MAVEN_OPTS不会传递。要配置maven-surefire-plugin使用的JVM大小,您需要:更改forkModenever(这不是一个好主意,因为Maven与测试无法隔离) ~或~ 使用argLine参数(正确的方式):在后一种情况下,可以使用以下内容:
<configuration>
  <argLine>-Xmx1024m</argLine>
</configuration>

但是我必须说,我倾向于同意Stephen的观点,你的测试中很可能有问题,我不确定给更多的内存是“解决”(隐藏?)你的问题的正确方法。

参考资料


1
你只在父级pom.xml中更新<configuration>标签吗? - Kevin Meredith
3
forkMode已被弃用:http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#forkMode - Macarse
1
@Macarse forkMode已被弃用,但我认为只是被forkCount替换,其功能类似。您可以使用MAVEN_OPTS的一种方式是<argLine>${env.MAVEN_OPTS}</argLine>,但显然不建议这样做,因为它可能因计算机而异(https://dev59.com/Smkv5IYBdhLWcg3wpCMz#10463133)。还要注意,如果您正在使用jacoco,则应以不同的方式设置argLine https://dev59.com/m2ct5IYBdhLWcg3wNqsg - rogerdpack

78

对于像我一样不熟悉Maven的新手,这里是整个配置需要放在pom的build部分中。干杯。

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.2</version>
        <configuration>
            <argLine>-Xmx1024m</argLine>
        </configuration>
      </plugin>
    </plugins>
  </build>

当在IntelliJ中启动JUnit测试时,您的解决方案会引发“JUnitException:TestEngine ID为'junit-jupiter'的测试无法被发现”的异常。 - Valerij Dobler

12

为了暂时解决这个问题,我发现以下方法是最快的:

export JAVA_TOOL_OPTIONS="-Xmx1024m -Xms1024m"

12

很有可能问题出在您要求Maven运行的单元测试中的一个。

因此,调整堆大小是错误的方法。相反,您应该查看导致OOME的单元测试,并尝试弄清楚它是单元测试的错还是被测试的代码的错。

首先查看堆栈跟踪。如果没有,请使用-e选项再次运行mvn ... test


1
@Stephen,我在运行配置中设置了-Xmx1024m后,可以在 Eclipse 中通过测试用例,但是当我在控制台上运行“mvn test”时,它总是抛出 OutOfMemoryError 错误,即使我添加了“mvn test -DMAVEN_OPTS=-Xmx1024m”的-e选项。 - zjffdu
3
@zjffdu - 你完全没有理解我的观点!添加“-e”的目的不是为了让测试工作。而是为了找出它们不能正常工作的原因。 - Stephen C
1
@zjffdu - 在这种情况下,您需要像处理其他Java问题一样通过艰苦的调试来解决它。 - Stephen C
2
在运行模拟完整浏览器环境的GWT测试用例时,我遇到了这个问题。有时候增加堆大小是可以解决的。 - djjeck
2
@djjeck - 是的,有时候会这样。但我认为大多数情况下这不是正确的解决方案。 - Stephen C
显示剩余4条评论

8

我已经从两个方面解决了这个问题:

  1. Adding this configuration in pom.xml

    <configuration><argLine>-Xmx1024m</argLine></configuration>
    
  2. Switch to used JDK 1.7 instead of 1.6


7

正如前面的答案所提到的,由于Surefire正在创建一个新的JVM来运行您的测试,因此您希望将-Xmx1024m传递给新的JVM,而不是您启动mvn test的JVM。

只是想补充一下,在命令中可以这样做:

mvn test -DargLine="-Xmx1024m"

在pom.xml文件中,添加JVM选项到Surefire插件的配置中,与此具有相同的效果:

<configuration>
  <argLine>-Xmx1024m</argLine>
</configuration>

5
为了解决Maven中的java.lang.OutOfMemoryError: Java heap space错误,请尝试在pom中配置以下设置。
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>${maven-surefire-plugin.version}</version>
     <configuration>
        <verbose>true</verbose>
        <fork>true</fork>
        <argLine>-XX:MaxPermSize=500M</argLine>
    </configuration>
</plugin>

1
如果您的内存溢出错误是由于在单元测试中创建新的HiveContext等加载大量类而引起的,那么提到MaxPermSize将会得到+1分。这就是您的解决方案。 - swdev
1
Oracle在JDK 8版本中完全删除了Perm gen space。因此,设置-XX:MaxPermSize将会给出一个警告:“OpenJDK 64位服务器VM警告:忽略选项MaxPermSize;支持已在8.0中删除”。 - user674669

-2

不仅仅是堆内存。为了解决Maven中出现的异常,还要增加perm size,并在环境变量中使用这些变量。

variable name: MAVEN_OPTS
variable value: -Xmx512m -XX:MaxPermSize=256m

例子:

export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=500m"

那么错误就不会是“Java堆空间”,而是其他的。 - Kalle Richter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接