• What means the errormessage 'java.lang.OutOfMemoryError: GC overhead limit exceeded' in Java? 规格严格


    转国内的:

    一、异常如下:
    Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

    二、解释:
    JDK6新增错误类型。当GC为释放很小空间占用大量时间时抛出。
    一般是因为堆太小。导致异常的原因:没有足够的内存。

    三、解决方案:

    1、查看系统是否有使用大内存的代码或死循环。
    2、可以添加JVM的启动参数来限制使用内存:-XX:-UseGCOverheadLimit

    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).

    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.

    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 this article for details (specifically this part).

    The GC throws this exception when too much time is spent in garbage collection for too little return, eg. 98% of CPU time is spent on GC and less than 2% of heap is recovered.

    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.

    You can turn this off with the command line option -XX:-UseGCOverheadLimit

    More info here

    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 Windows7 32 bit.

    java -Xloggc:gc.log GarbageCollector

    Then look at gc.log

    • Triggered 444 times using BAD method
    • Triggered 666 times using WORSE method
    • Triggered 354 times using BETTER method

    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...

  • 相关阅读:
    使用PHP调用TinyURL API的方法
    基于MySQL数据库的UTF8中文网站全文检索的实现
    PHP版单点登陆实现方案
    php框架codeigniter是如何实现mvc模式以及单一入口
    网友分享:二十五个顶级PHP模板引擎整理
    数据库置疑的处理办法
    使用Log Explorer恢复数据
    使用Log Explorer恢复数据
    11个故事 11个道理
    VS2008 WinForm 去掉DataGridView最后一行的那个空白行
  • 原文地址:https://www.cnblogs.com/diyunpeng/p/2054500.html
Copyright © 2020-2023  润新知