Android Studio使用gradle进行编译打包产生 java.lang.OutOfMemoryError: GC overhead limit exceeded

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_36570478/article/details/81539569

如果只关心解决方案,在gradle.properites文件中添加如下配置即可(4096m = 4g,具体依个人情况设置大小):

org.gradle.jvmargs=-Xmx4096m

或者使用内存运允许的情况下 建议使用如下配置

org.gradle.jvmargs=-Xmx4096m -Xms4096m

分析过程

什么导致了 GC overhead limit exceeded ?

Java运行环境包含了内置的垃圾回收(GC)进程,在很多其他语言中,开发者需要人工分配和回收内存。

在Java中你只需要申请内存分配,当内存不够用时,GC将被自动调用进行垃圾内存回收。

 java.lang.OutOfMemoryError: GC overhead limit exceeded 则表示程序消耗了太多的可用内存,并且GC屡屡没能有效回收清理。

JVM默认配置下,如果它使用了超过98%的时间进行垃圾回收,并且只用不超过2%的堆被回收,则会抛出此异常。这就意味着完成一次GC后大部分的堆空间任然被占用,而被清理出来的2%的堆也会很快被填满,从而再次触发GC调用,这种GC的频繁调用将使CPU的一直处于高负荷状态,由于GC过度频繁运行,客户程序也将无法正常往下运行导致程序崩溃。

怎么解决 GC overhead limit exceeded ?

从上面我们知道出现这类异常的原因是回收的有效内存太少,GC触发过于频繁。所以,我们可以通过扩大内存或者排除内存泄露两个方面来解决问题,这是gradle抛出的异常,所以我们很难从阻止内存泄露下手,只能选择扩大内存。

怎样扩大内存?

通过以下途径手动设置:

-Xms128m JVM初始分配的堆内存

-Xmx512m JVM最大允许分配的堆内存,按需分配

-XX:PermSize=64M JVM初始分配的非堆内存

-XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配

关于JVM内存与分配

关于为何要将-Xms与-Xmx设为一致,这里有一段说明(from:https://developer.jboss.org/thread/149559):

In a production environment, if you monitor the GC data, you will notice that is a relatively short period of time (usually less than an hour), the JVM will eventually increase the heap size to the -Xmx setting. Each time the JVM increases the heap size it must ask the OS for additional memory, which takes time (and thus adds to the response time of any requests that were is process when the GC hit). And usually the JVM will never let go of that memeory. Therefore, since the JVM will eventually grab the -Xmx memory, you might as well set it to that at the beginning.

Another point is that with a smaller heap size (starting with -Xms), GCs will happen more often. So by starting with a larger heap initially the GCs will happen not as often.

Finally, in a production environment, you usually run only one app server per OS (or per VM). So since the app server is not competing for memory with other apps you might as well give it the memory up front.

Note that the above is for production. It applies also to the syatem test environment since the system test environment should mimic production as close as possible.

For development, make -Xms and -Xmx different. Usually, you are not doing much work with the app server in development, so it will often stay with the -Xms heap setting. Also, since in development the app server will share the machine with lots of other apps (mail client, word processors, IDEs, databases, browsers, etc), setting the -Xms to a smaller size lets the app server play more nicely with the other software that is also competing for the same resources.

猜你喜欢

转载自blog.csdn.net/weixin_36570478/article/details/81539569