我在执行JUnit
测试时收到此错误消息:
java.lang.OutOfMemoryError: GC overhead limit exceeded
我知道 anOutOfMemoryError
是什么,但是 GC 开销限制是什么意思?我该如何解决这个问题?
我在执行JUnit
测试时收到此错误消息:
java.lang.OutOfMemoryError: GC overhead limit exceeded
我知道 anOutOfMemoryError
是什么,但是 GC 开销限制是什么意思?我该如何解决这个问题?
此消息意味着由于某种原因,垃圾收集器占用了过多的时间(默认为进程所有 CPU 时间的 98%)并且在每次运行中恢复的内存非常少(默认为堆的 2%)。
这实际上意味着您的程序停止任何进展,并且一直忙于运行垃圾收集。
为了防止您的应用程序在没有完成任何操作的情况下占用 CPU 时间,JVM 会抛出此错误Error
,以便您有机会诊断问题。
我见过这种情况发生的罕见情况是,一些代码在内存已经非常受限的环境中创建了大量临时对象和大量弱引用对象。
查看 Java GC 调整指南,该指南适用于各种 Java 版本,并包含有关此特定问题的部分:
引用 Oracle 的文章“Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning”:
GC 时间过长和 OutOfMemoryError
如果垃圾收集花费的时间过多,并行收集器将抛出 OutOfMemoryError:如果垃圾收集花费的时间超过总时间的 98%,并且回收的堆少于 2%,则会抛出 OutOfMemoryError。此功能旨在防止应用程序长时间运行,同时由于堆太小而几乎没有进展或没有进展。
-XX:-UseGCOverheadLimit
如有必要,可以通过将选项添加到命令行来禁用此功能。
编辑:看起来有人可以比我打字快:)
通常是代码。这是一个简单的例子:
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");
}
}
在 Windows 7 32 位上使用 Java 1.6.0_24-b07。
java -Xloggc:gc.log GarbageCollector
然后看gc.log
现在承认,这不是最好的测试或最好的设计,但是当面对你别无选择只能实现这样一个循环的情况时,或者在处理表现不佳的现有代码时,选择重用对象而不是创建新对象可以减少垃圾收集器阻碍的次数......
根据Java [8] Platform, Standard Edition Troubleshooting Guide的错误原因:(添加了强调和换行符)
[...]“超出 GC 开销限制”表示垃圾收集器一直在运行,Java 程序的进度非常缓慢。
垃圾回收后,如果Java 进程花费超过大约 98% 的时间进行垃圾回收,并且如果它回收的堆少于 2%,并且到目前为止一直在做最后 5 个(编译时间常数)连续垃圾集合,然后
java.lang.OutOfMemoryError
抛出 a。[...]
除了使用 - 设置堆内存之外Xms1g -Xmx2g
,请尝试
-XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m
-XX:ParallelGCThreads=n -XX:ConcGCThreads=n
查看有关 G1GC 的更多相关问题
只需通过在中设置此选项来稍微增加堆大小
运行 → 运行配置 → 参数 → VM 参数
-Xms1024M -Xmx2048M
Xms - 最小限制
Xmx - 最大限制
试试这个
打开build.gradle
文件
android {
dexOptions {
javaMaxHeapSize = "4g"
}
}
以下对我有用。只需添加以下代码段:
android {
compileSdkVersion 25
buildToolsVersion '25.0.1'
defaultConfig {
applicationId "yourpackage"
minSdkVersion 10
targetSdkVersion 25
versionCode 1
versionName "1.0"
multiDexEnabled true
}
dexOptions {
javaMaxHeapSize "4g"
}
}
在 build.gradle(Module:app) 文件中增加 javaMaxHeapsize
dexOptions {
javaMaxHeapSize "1g"
}
到(在gradle中添加这一行)
dexOptions {
javaMaxHeapSize "4g"
}
已解决:
只需添加
org.gradle.jvmargs=-Xmx1024m
,
gradle.properties
如果它不存在,则创建它。
您还可以通过将其添加到文件中来增加内存分配和堆大小gradle.properties
:
org.gradle.jvmargs=-Xmx2048M -XX\:MaxHeapSize\=32g
不一定非要2048M和32g,随心所欲。
Java 堆大小描述(xms、xmx、xmn)
-Xms size in bytes
Example : java -Xms32m
设置 Java 堆的初始大小。默认大小为 2097152 (2MB)。这些值必须是 1024 字节 (1KB) 的倍数且大于 1024 字节 (1KB)。(-server 标志将默认大小增加到 32M。)
-Xmn size in bytes
Example : java -Xmx2m
设置 Eden 生成的初始 Java 堆大小。默认值为 640K。(-server 标志将默认大小增加到 2M。)
-Xmx size in bytes
Example : java -Xmx2048m
设置 Java 堆可以增长到的最大大小。默认大小为 64M。(-server 标志将默认大小增加到 128M。)最大堆限制约为 2 GB (2048MB)。
Java 内存参数(xms、xmx、xmn)格式
设置 Java 堆大小时,您应该使用字母“m”或“M”中的一个来指定内存参数,或者使用“g”或“G”来表示 GB。如果您指定“MB”或“GB”,您的设置将不起作用。有效参数如下所示:
-Xms64m 或 -Xms64M -Xmx1g 或 -Xmx1G 也可以使用 2048MB 来指定 2GB 另外,请确保在指定参数时只使用整数。使用 -Xmx512m 是一个有效的选项,但 -Xmx0.5g 会导致错误。
此参考可能对某人有所帮助。
我在 Android Studio 中工作,并在尝试生成已签名的 APK 以供发布时遇到此错误。我能够毫无问题地构建和测试调试 APK,但是一旦我想构建发布 APK,构建过程将连续运行几分钟,然后最终以“错误 java.lang.OutOfMemoryError: GC超出开销限制”。我增加了 VM 和 Android DEX 编译器的堆大小,但问题仍然存在。最后,经过几个小时和大杯咖啡,问题出在我的应用程序级“build.gradle”文件中——我将发布构建类型的“minifyEnabled”参数设置为“false”,因此运行 Proguard 的东西关于尚未通过代码收缩过程的代码(请参阅https://developer.android.)。我将“minifyEnabled”参数更改为“true”,并且发布版本像梦一样执行:)
简而言之,我必须将我的应用程序级“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
}
}
//...
到
//...
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
}
}
//...
要增加 IntelliJ IDEA 中的堆大小,请按照以下说明进行操作。它对我有用。
对于 Windows 用户,
转到安装IDE的位置并搜索以下内容。
idea64.exe.vmoptions
编辑文件并添加以下内容。
-Xms512m
-Xmx2024m
-XX:MaxPermSize=700m
-XX:ReservedCodeCacheSize=480m
这就对了 !!
您需要在 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**
)
和
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**
在 Netbeans 中,设计最大堆大小可能会有所帮助。转到运行=>设置项目配置=>自定义。在其弹出的运行窗口中,进入VM Option,填写-Xms2048m -Xmx2048m
. 它可以解决堆大小问题。
我不知道这是否仍然相关,但只想分享对我有用的东西。
将 kotlin 版本更新到可用的最新版本。https://blog.jetbrains.com/kotlin/category/releases/
它完成了。
@Buhb 我在它的主要方法中的一个普通的spring-boot Web应用程序中复制了这个。这是代码:
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());
}
}
引起来的示例代码也来自 oracle java8 语言规范。
使用 Oracle Web 逻辑服务器时出现此错误。我正在分享我的答案以供参考,以防有人最终在这里寻找解决方案。
因此,如果您尝试启动 Oracle Web 逻辑服务器并遇到此错误,那么您只需增加为运行服务器设置的初始堆大小和最大堆大小。
转到 - > C:\Oracle\Middleware\Oracle_Home\user_projects\domains\wl_server\bin
打开setDomainEnv.cmd
检查设置 USER_MEM_ARGS值,如果小于则
设置 USER_MEM_ARGS="-Xms128m – Xmx8192m ${MEM_DEV_ARGS} ${MEM_MAX_PERM_SIZE}"
这意味着您的初始堆大小设置为 128 MB,最大堆大小为 8GB。现在,只需保存文件并重新启动服务器。如果它没有解决问题,请尝试增加大小或寻找优化服务的方法。
对于参考,请查看此链接:https ://docs.oracle.com/cd/E49933_01/server.770/es_install/src/tins_postinstall_jvm_heap.html
编辑:检查您是否能够在运行服务器时看到更新的 java args。就像这样 如果它像以前一样出现,那么通过简单的搜索和替换来替换 setDoaminEnv.cmd 中显示的值。
重新启动我的 MacBook 为我解决了这个问题。