简体   繁体   English

错误 java.lang.OutOfMemoryError:超出 GC 开销限制

[英]Error java.lang.OutOfMemoryError: GC overhead limit exceeded

I get this error message as I execute my JUnit tests:我在执行JUnit测试时收到此错误消息:

java.lang.OutOfMemoryError: GC overhead limit exceeded

I know what an OutOfMemoryError is, but what does GC overhead limit mean?我知道OutOfMemoryError是什么,但是 GC 开销限制是什么意思? How can I solve this?我该如何解决这个问题?

This message means that for some reason the garbage collector is taking an excessive amount of time (by default 98% of all CPU time of the process) and recovers very little memory in each run (by default 2% of the heap).此消息意味着由于某种原因垃圾收集器占用了过多的时间(默认为进程所有 CPU 时间的 98%)并且在每次运行中回收的内存非常少(默认为堆的 2%)。

This effectively means that your program stops doing any progress and is busy running only the garbage collection at all time.这实际上意味着您的程序停止执行任何进度并且一直忙于仅运行垃圾收集。

To prevent your application from soaking up CPU time without getting anything done, the JVM throws this Error so that you have a chance of diagnosing the problem.为了防止您的应用程序在没有完成任何事情的情况下占用 CPU 时间,JVM 会抛出此Error以便您有机会诊断问题。

The rare cases where I've seen this happen is where some code was creating tons of temporary objects and tons of weakly-referenced objects in an already very memory-constrained environment.我见过这种情况发生的极少数情况是,一些代码在已经非常受内存限制的环境中创建了大量临时对象和大量弱引用对象。

Check out the Java GC tuning guide, which is available for various Java versions and contains sections about this specific problem:查看 Java GC 调优指南,该指南适用于各种 Java 版本,并包含有关此特定问题的部分:

Quoting from Oracle's article "Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning" :引用 Oracle 的文章“Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning”

Excessive GC Time and OutOfMemoryError GC 时间过长和 OutOfMemoryError

The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown.如果垃圾收集花费了太多时间,并行收集器将抛出 OutOfMemoryError:如果超过 98% 的总时间花费在垃圾收集上,而回收的堆不到 2%,则会抛出 OutOfMemoryError。 This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small.此功能旨在防止应用程序长时间运行而由于堆太小而进展甚微或没有进展。 If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.如有必要,可以通过在命令行中添加选项-XX:-UseGCOverheadLimit来禁用此功能。

EDIT: looks like someone can type faster than me :)编辑:看起来有人可以比我打字更快:)

If you are sure there are no memory leaks in your program, try to:如果您确定程序中没有内存泄漏,请尝试:

  1. Increase the heap size, for example -Xmx1g .增加堆大小,例如-Xmx1g
  2. Enable the concurrent low pause collector -XX:+UseConcMarkSweepGC .启用并发低暂停收集器-XX:+UseConcMarkSweepGC
  3. Reuse existing objects when possible to save some memory.尽可能重用现有对象以节省一些内存。

If necessary, the limit check can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.如有必要,可以通过在命令行中添加选项-XX:-UseGCOverheadLimit来禁用限制检查

It's usually the code.通常是代码。 Here's a simple example:这是一个简单的例子:

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

Using Java 1.6.0_24-b07 on a Windows 7 32 bit.在 Windows 7 32 位上使用 Java 1.6.0_24-b07。

java -Xloggc:gc.log GarbageCollector

Then look at gc.log然后看gc.log

  • Triggered 444 times using BAD method使用 BAD 方法触发 444 次
  • Triggered 666 times using WORSE method使用 WORSE 方法触发 666 次
  • Triggered 354 times using BETTER method使用 BETTER 方法触发 354 次

Now granted, this is not the best test or the best design but when faced with a situation where you have no choice but implementing such a loop or when dealing with existing code that behaves badly, choosing to reuse objects instead of creating new ones can reduce the number of times the garbage collector gets in the way...现在承认,这不是最好的测试或最好的设计,但是当面临这样的情况时,您别无选择,只能实现这样的循环,或者在处理表现不佳的现有代码时,选择重用对象而不是创建新对象可以减少垃圾收集器妨碍的次数...

Cause for the error according to the Java [8] Platform, Standard Edition Troubleshooting Guide : (emphasis and line breaks added)根据Java [8] Platform, Standard Edition 故障排除指南中的错误原因:(添加了强调和换行符)

[...] "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress. [...]“超出GC开销限制”表示垃圾收集器一直在运行并且Java程序进展非常缓慢。

After a garbage collection, if the Java process is spending more than approximately 98% of its time doing garbage collection and if it is recovering less than 2% of the heap and has been doing so far the last 5 (compile time constant) consecutive garbage collections, then a java.lang.OutOfMemoryError is thrown.在垃圾回收之后,如果Java 进程花费了大约 98% 以上的时间进行垃圾回收,并且如果它正在回收不到 2% 的堆并且到目前为止一直在做最后 5 个(编译时间常数)连续垃圾集合,然后抛出java.lang.OutOfMemoryError [...] [...]

  1. Increase the heap size if current heap is not enough.如果当前堆不够,则增加堆大小
  2. If you still get this error after increasing heap memory, use memory profiling tools like MAT ( Memory analyzer tool), Visual VM etc and fix memory leaks.如果在增加堆内存后仍然出现此错误,请使用内存分析工具,MAT (内存分析器工具)、 Visual VM等并修复内存泄漏。
  3. Upgrade JDK version to latest version ( 1.8.x) or at least 1.7.x and use G1GC algorithm.将 JDK 版本升级到最新版本 (1.8.x) 或至少 1.7.x 并使用 G1GC 算法。 . . The throughput goal for the G1 GC is 90 percent application time and 10 percent garbage collection time G1 GC 的吞吐量目标是 90% 的应用程序时间和 10% 的垃圾收集时间
  4. Apart from setting heap memory with - Xms1g -Xmx2g , try除了使用 - Xms1g -Xmx2g设置堆内存Xms1g -Xmx2g ,还可以尝试

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m -XX:ParallelGCThreads=n -XX:ConcGCThreads=n

Have a look at some more related questions regarding G1GC看看一些关于 G1GC 的更多相关问题

Just increase the heap size a little by setting this option in只需通过在其中设置此选项来稍微增加堆大小

Run → Run Configurations → Arguments → VM arguments运行 → 运行配置 → 参数 → VM 参数

-Xms1024M -Xmx2048M

Xms - for minimum limit Xms - 最低限度

Xmx - for maximum limit Xmx - 最大限制

try this试试这个

open the build.gradle file打开build.gradle文件

  android {
        dexOptions {
           javaMaxHeapSize = "4g"
        }
   }

For me, the following steps worked:对我来说,以下步骤有效:

  1. Open the eclipse.ini file打开eclipse.ini文件
  2. Change改变

    -Xms40m -Xmx512m

    to

    -Xms512m -Xmx1024m
  3. Restart Eclipse重启 Eclipse

See here 看这里

The following worked for me.以下对我有用。 Just add the following snippet:只需添加以下代码段:

android {
        compileSdkVersion 25
        buildToolsVersion '25.0.1'

defaultConfig {
        applicationId "yourpackage"
        minSdkVersion 10
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
dexOptions {
        javaMaxHeapSize "4g"
    }
}

increase javaMaxHeapsize in your build.gradle(Module:app) file在 build.gradle(Module:app) 文件中增加 javaMaxHeapsize

dexOptions {
    javaMaxHeapSize "1g"
}

to (Add this line in gradle)到(在gradle中添加这一行)

 dexOptions {
        javaMaxHeapSize "4g"
    }

Solved:解决了:
Just add只需添加
org.gradle.jvmargs=-Xmx1024m
in
gradle.properties
and if it does not exist, create it.如果它不存在,则创建它。

You can also increase memory allocation and heap size by adding this to your gradle.properties file:您还可以通过将其添加到gradle.properties文件来增加内存分配和堆大小:

org.gradle.jvmargs=-Xmx2048M -XX\\:MaxHeapSize\\=32g

It doesn't have to be 2048M and 32g, make it as big as you want.不一定要2048M和32g,想多大就多大。

Java heap size descriptions (xms, xmx, xmn) Java 堆大小描述(xms、xmx、xmn)

-Xms size in bytes

Example : java -Xms32m

Sets the initial size of the Java heap.设置 Java 堆的初始大小。 The default size is 2097152 (2MB).默认大小为 2097152 (2MB)。 The values must be a multiple of, and greater than, 1024 bytes (1KB).这些值必须是 1024 字节 (1KB) 的倍数且大于 1024 字节。 (The -server flag increases the default size to 32M.) (-server 标志将默认大小增加到 32M。)

-Xmn size in bytes

Example : java -Xmx2m

Sets the initial Java heap size for the Eden generation.设置 Eden 代的初始 Java 堆大小。 The default value is 640K.默认值为 640K。 (The -server flag increases the default size to 2M.) (-server 标志将默认大小增加到 2M。)

-Xmx size in bytes

Example : java -Xmx2048m

Sets the maximum size to which the Java heap can grow.设置 Java 堆可以增长到的最大大小。 The default size is 64M.默认大小为 64M。 (The -server flag increases the default size to 128M.) The maximum heap limit is about 2 GB (2048MB). (-server 标志将默认大小增加到 128M。)最大堆限制约为 2 GB (2048MB)。

Java memory arguments (xms, xmx, xmn) formatting Java 内存参数(xms、xmx、xmn)格式化

When setting the Java heap size, you should specify your memory argument using one of the letters “m” or “M” for MB, or “g” or “G” for GB.在设置 Java 堆大小时,您应该使用字母“m”或“M”之一(代表 MB,或“g”或“G”代表 GB)指定内存参数。 Your setting won't work if you specify “MB” or “GB.”如果您指定“MB”或“GB”,您的设置将不起作用。 Valid arguments look like this:有效参数如下所示:

-Xms64m or -Xms64M -Xmx1g or -Xmx1G Can also use 2048MB to specify 2GB Also, make sure you just use whole numbers when specifying your arguments. -Xms64m 或 -Xms64M -Xmx1g 或 -Xmx1G 也可以使用 2048MB 来指定 2GB 此外,请确保在指定参数时只使用整数。 Using -Xmx512m is a valid option, but -Xmx0.5g will cause an error.使用 -Xmx512m 是一个有效选项,但 -Xmx0.5g 会导致错误。

This reference can be helpful for someone.此参考资料可能对某人有所帮助。

I'm working in Android Studio and encountered this error when trying to generate a signed APK for release.我在 Android Studio 中工作并在尝试生成已签名的 APK 以供发布时遇到此错误。 I was able to build and test a debug APK with no problem, but as soon as I wanted to build a release APK, the build process would run for minutes on end and then finally terminate with the "Error java.lang.OutOfMemoryError: GC overhead limit exceeded".我能够毫无问题地构建和测试调试 APK,但是一旦我想构建发布版 APK,构建过程就会连续运行几分钟,然后最终以“Error java.lang.OutOfMemoryError: GC超出开销限制”。 I increased the heap sizes for both the VM and the Android DEX compiler, but the problem persisted.我增加了 VM 和 Android DEX 编译器的堆大小,但问题仍然存在。 Finally, after many hours and mugs of coffee it turned out that the problem was in my app-level 'build.gradle' file - I had the 'minifyEnabled' parameter for the release build type set to 'false', consequently running Proguard stuffs on code that hasn't been through the code-shrinking' process (see https://developer.android.com/studio/build/shrink-code.html ).最后,经过几个小时的喝咖啡,结果发现问题出在我的应用程序级“build.gradle”文件中——我将发布构建类型的“minifyEnabled”参数设置为“false”,因此运行 Proguard 的东西关于尚未通过代码缩减过程的代码(请参阅https://developer.android.com/studio/build/shrink-code.html )。 I changed the 'minifyEnabled' parameter to 'true' and the release build executed like a dream :)我将“minifyEnabled”参数更改为“true”,并且发布版本像梦一样执行:)

In short, I had to change my app-level 'build.gradle' file from: //...简而言之,我必须从以下位置更改我的应用程序级“build.gradle”文件://...

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.sign_config_release
    }
    debug {
        debuggable true
        signingConfig signingConfigs.sign_config_debug
    }
}

//...

to

    //...

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.sign_config_release
    }
    debug {
        debuggable true
        signingConfig signingConfigs.sign_config_debug
    }
}

//...

To increase heap size in IntelliJ IDEA follow the following instructions.要在 IntelliJ IDEA 中增加堆大小,请遵循以下说明。 It worked for me.它对我有用。

For Windows Users,对于 Windows 用户,

Go to the location where IDE is installed and search for following.转到IDE安装的位置并搜索以下内容。

idea64.exe.vmoptions

Edit the file and add the following.编辑文件并添加以下内容。

-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m

That is it !!这就对了 !!

you can try to make changes on the server setting by referring to this image and increase the memory size for processing process changes highlighted in yellow您可以尝试通过参考此图像对服务器设置进行更改,并增加内存大小以处理以黄色突出显示的进程更改

you can also make changes to java heap by opening cmd-> set _java_opts -Xmx2g您还可以通过打开 cmd-> set _java_opts -Xmx2g来更改 java 堆
2g(2gigabytes) depending upon the complexity of your program 2g(2gigabytes) 取决于程序的复杂性

try to use less constant variable and temp variables尝试使用较少的常量变量和临时变量

在此处输入图片说明

You need to increase the memory size in Jdeveloper go to setDomainEnv.cmd .您需要在 Jdeveloper 中增加内存大小,请转到setDomainEnv.cmd

set WLS_HOME=%WL_HOME%\server    
set XMS_SUN_64BIT=**256**
set XMS_SUN_32BIT=**256**
set XMX_SUN_64BIT=**3072**
set XMX_SUN_32BIT=**3072**
set XMS_JROCKIT_64BIT=**256**
set XMS_JROCKIT_32BIT=**256**
set XMX_JROCKIT_64BIT=**1024**
set XMX_JROCKIT_32BIT=**1024**

if "%JAVA_VENDOR%"=="Sun" (
    set WLS_MEM_ARGS_64BIT=**-Xms256m -Xmx512m**
    set WLS_MEM_ARGS_32BIT=**-Xms256m -Xmx512m**
) else (
    set WLS_MEM_ARGS_64BIT=**-Xms512m -Xmx512m**
    set WLS_MEM_ARGS_32BIT=**-Xms512m -Xmx512m**
)

and

set MEM_PERM_SIZE_64BIT=-XX:PermSize=**256m**
set MEM_PERM_SIZE_32BIT=-XX:PermSize=**256m**

if "%JAVA_USE_64BIT%"=="true" (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_64BIT%
) else (
    set MEM_PERM_SIZE=%MEM_PERM_SIZE_32BIT%
)

set MEM_MAX_PERM_SIZE_64BIT=-XX:MaxPermSize=**1024m**
set MEM_MAX_PERM_SIZE_32BIT=-XX:MaxPermSize=**1024m**

In Netbeans, it may be helpful to design a max heap size.在 Netbeans 中,设计最大堆大小可能会有所帮助。 Go to Run => Set Project Configuration => Customise .转到运行=>设置项目配置=>自定义 In the Run of its popped up window, go to VM Option , fill in -Xms2048m -Xmx2048m .在弹出窗口的Run中,转到VM Option ,填写-Xms2048m -Xmx2048m It could solve heap size problem.它可以解决堆大小问题。

I don't know if this is still relevant or not, but just want to share what worked for me.我不知道这是否仍然相关,但只是想分享对我有用的东西。

Update kotlin version to latest available.将 kotlin 版本更新为可用的最新版本。 https://blog.jetbrains.com/kotlin/category/releases/ https://blog.jetbrains.com/kotlin/category/releases/

and it's done.它完成了。

@Buhb I reproduced this by this in an normal spring-boot web application within its main method. @Buhb 我在其主要方法中的普通 spring-boot Web 应用程序中复制了这个。 Here is the code:这是代码:

public static void main(String[] args) {
    SpringApplication.run(DemoServiceBApplication.class, args);
    LOGGER.info("hello.");
    int len = 0, oldlen=0;
    Object[] a = new Object[0];
    try {
        for (; ; ) {
            ++len;
            Object[] temp = new Object[oldlen = len];
            temp[0] = a;
            a = temp;
        }
    } catch (Throwable e) {
        LOGGER.info("error: {}", e.toString());
    }
}

The sample code that caused an come is also from oracle java8 language specifications.引起来的示例代码也是来自oracle java8语言规范。

I got this error while working with Oracle web logic server.我在使用 Oracle Web 逻辑服务器时遇到此错误。 I am sharing my answer for reference in case someone end up here looking for the solution.我正在分享我的答案以供参考,以防有人最终在这里寻找解决方案。

So, if you are trying to up the Oracle web logic server and got this error then you just have to increase the initial and maximum heap size set for running the server.因此,如果您尝试启动 Oracle Web 逻辑服务器并遇到此错误,那么您只需增加为运行服务器设置的初始和最大堆大小。

Go to - > C:\\Oracle\\Middleware\\Oracle_Home\\user_projects\\domains\\wl_server\\bin转至 -> C:\\Oracle\\Middleware\\Oracle_Home\\user_projects\\domains\\wl_server\\bin

open setDomainEnv.cmd打开setDomainEnv.cmd

check set USER_MEM_ARGS value , if its less then检查设置 USER_MEM_ARGS值,如果它小于

set USER_MEM_ARGS="-Xms128m – Xmx8192m ${MEM_DEV_ARGS} ${MEM_MAX_PERM_SIZE}"设置 USER_MEM_ARGS="-Xms128m – Xmx8192m ${MEM_DEV_ARGS} ${MEM_MAX_PERM_SIZE}"

This means that your intital heap size is set to 128 MB and max heap size is 8GB.这意味着您的初始堆大小设置为 128 MB,最大堆大小设置为 8GB。 Now , just save the file and restart the server.现在,只需保存文件并重新启动服务器。 if it didn't resolve the issue, try increasing the size or look for ways to optimizing the service.如果它没有解决问题,请尝试增加大小或寻找优化服务的方法。

for ref , check this link : https://docs.oracle.com/cd/E49933_01/server.770/es_install/src/tins_postinstall_jvm_heap.html对于参考,请检查此链接: https : //docs.oracle.com/cd/E49933_01/server.770/es_install/src/tins_postinstall_jvm_heap.html

edit: Check whether you are able to see the updated java args while running the server .编辑:检查您是否能够在运行服务器时看到更新的 java args。 just like this像这样在此处输入图片说明 If its coming as before then replace the shown value from setDoaminEnv.cmd by simple search and replace.如果它像以前一样出现,那么通过简单的搜索和替换来替换 setDoaminEnv.cmd 中显示的值。

重新启动我的 MacBook 为我解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取错误:java.lang.OutOfMemoryError:超出了GC开销限制 - Getting Error:java.lang.OutOfMemoryError: GC overhead limit exceeded 错误:java.lang.OutOfMemoryError:超出了GC开销限制 - Error:java.lang.OutOfMemoryError: GC overhead limit exceeded IntelliJ 错误:java.lang.OutOfMemoryError:超出 GC 开销限制 - IntelliJ Error: java.lang.OutOfMemoryError: GC overhead limit exceeded Java PreparedStatement java.lang.OutOfMemoryError:超出了GC开销限制 - Java PreparedStatement java.lang.OutOfMemoryError: GC overhead limit exceeded 詹金斯 java.lang.OutOfMemoryError:超出 GC 开销限制 - Jenkins java.lang.OutOfMemoryError: GC overhead limit exceeded java.lang.OutOfMemoryError:GC开销限制超出了android studio - java.lang.OutOfMemoryError: GC overhead limit exceeded android studio Gridgain:java.lang.OutOfMemoryError:超出了GC开销限制 - Gridgain: java.lang.OutOfMemoryError: GC overhead limit exceeded Spark失败了java.lang.OutOfMemoryError:超出了GC开销限制? - Spark fails with java.lang.OutOfMemoryError: GC overhead limit exceeded? SonarQube java.lang.OutOfMemoryError:超出了GC开销限制 - SonarQube java.lang.OutOfMemoryError: GC overhead limit exceeded Tomcat java.lang.OutOfMemoryError:超出了GC开销限制 - Tomcat java.lang.OutOfMemoryError: GC overhead limit exceeded
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM