• OutOfMemoryError GC overhead limit exceeded


    今天在代码调试过程中,在通过swagger调试某个接口(restful api)的时候,遇到了该错误:OutOfMemoryError GC overhead limit exceeded 

    通过百度之后,知道该错误产生的原因是:jvm的垃圾回收期回收效率太低,并且多次触发gc之后,还是无法有效回收内存。

    显然,该错误是我的代码中,迅速且持续不断的产生新的对象,导致jvm一直gc,并且每次gc过后,又有一堆新的对象产生了,故而又重新触发gc,如此反复循环,jvm一直忙于gc,电脑的cpu和内存使用率一直居高不下,几乎都跑满100%,系统非常的卡顿,无法处理其他事情,这个系统一直维持着这样一种超负荷状态,但就是不会奔溃,反而是我要奔溃了。

    分析原因过程:

      一开始是,打算用jvm内存分析工具,来查看问题,比如plumbr, VisualVM, JConsole等,但是第一次用不熟悉,只能看到cpu和内存波动很大 ,无法有效定位问题。

      现在先撇开工具,

      ……

      我猜想是,代码中出现了无限递归、死循环或者死锁的情况。

      首先是无限递归,这种情况应该可以排除,因为这种情况已出现的话,系统是直接奔溃,报错应该是 stackOverFlow。 

      然后是死锁,这种情况是多线程的调度问题,而我写的代码里面,没有涉及到线程的调度,估计也不是这种情况。

      最后就剩下死循环的情况了。

      ……

      经过了几个世纪的挣扎,突然灵光一闪,会不会是之前加入的接口数据返回格式统一配置这里,出了问题,在解析返回数据时,出现了死循环。

      看了下代码:

      

    public static List<Field> getAllFields(Object object) {
            List<Field> allFields = new ArrayList<>();
            Class<?> aClass = object.getClass();
    
            allFields.addAll(Arrays.asList(aClass.getDeclaredFields()));
    
            while (aClass.getSuperclass() != Object.class && aClass.getSuperclass() != null) {
                aClass = object.getClass().getSuperclass();
                allFields.addAll(Arrays.asList(aClass.getDeclaredFields()));
            }
            return allFields;
        }

      终于找到问题原因所在了,自己写的方法,有个严重bug:对象的类型(aClass)迭代无效,一直是同一个。修改代码如下即可:

    public static List<Field> getAllFields(Object object) {
            List<Field> allFields = new ArrayList<>();
            Class<?> aClass = object.getClass();
    
            while (aClass != Object.class && aClass != null) {
                allFields.addAll(Arrays.asList(aClass.getDeclaredFields()));
    
                aClass = aClass.getSuperclass();
            }
            return allFields;
        }

    以此为戒,以后写过的函数,要经过仔细的测试,尤其涉及到循环和递归的东西,更要慎重,注意其结束条件。

  • 相关阅读:
    A Simple PlugIn Library For .NET
    (转).NET 一次查询多表,填充DataSet并指定表名(DataSet指定DataTable名称的技巧)
    Database Schema Create
    C++中关于指针入门的最好的文章
    oleDbCommand访问Excel
    the best simple c++
    c++连接数据库
    plugin framework 1
    c# invoke c++
    摩根士丹利赐与新浪增持评级
  • 原文地址:https://www.cnblogs.com/zhangxuezhi/p/11763441.html
Copyright © 2020-2023  润新知