美文网首页
GC频繁排查过程

GC频繁排查过程

作者: williamlee | 来源:发表于2020-11-28 12:56 被阅读0次

不喜欢看文字可以跳转[B站视频](https://www.bilibili.com/video/BV1vy4y1q7GQ/)

定时任务备份表task数据到task_history中,备份后将原数据删除。

如下示例:

```

    @Scheduled(fixedDelay = 5)

    public String taskBackUp() {

        while (true) {

            try {

                boolean flag = selfProxy.process();

                if (flag) break;

            } catch (Exception e) {

            }

        }

        return "success";

    }

    @Transactional(rollbackFor = Exception.class)

    public boolean process() {

        List<Task> list = taskMapper.getList();

        if (CollectionUtils.isEmpty(list)) {

            return true;

        }

        List<TaskHistory> historyList = list.stream().map(t -> {

            TaskHistory ts = new TaskHistory();

            BeanUtils.copyProperties(t, ts);

            return ts;

        }).collect(Collectors.toList());

        //将数据插入历史表

        taskHistoryMapper.insert(historyList);

        //删除原表数据 这里会报错

        taskMapper.delete(list);

        return false;

    }

```

上线触发定时任务后收到gc报警,应用吞吐量下降。因为实现时出现bug导致delete时抛出异常,数据产生回滚,但是外层做了catch,不会打断循环。也就是原本是想一点点备份数据直到备份完成,但是因为产生异常导致每次都是处理第一批数据,造成了死循环。这个是产生问题的原因,通过异常日志是能够定位到的。

但是这个case我想在日志不明确时可以通过什么手段能定位到该问题呢?所以将异常日志移除。看是否通过其他手段定位到在异常信息不明确时定位到问题。

答案:

在不确定的情况下还是整体看下进程情况吧。

执行`java -jar /chaosblade-0.6.0/arthas-boot.jar`选择进程,输入`dashboard`可以看到整体的情况。如图:

可以看到有个线程**长期**占用CPU99%,这个线程肯定有问题。另外观察到`gc.parnew.count`与`gc.concurrentmarksweep.count`增长的速度也比较快。

下面异常的线程在做什么:

执行多次`thread 41(41是线程id)`可以看到都是在执行sql查询操作。

再去查看线程栈中对应代码以及sql查询日志便能够定位到是产生了死循环导致的。

另外还有一种方式就是针对内存做profile,查看到分配内存最多的线程,然后看其线程栈也能找到原因,这种方法交给大家自己探索下,有问题可以在下方留言。

相关文章

网友评论

      本文标题:GC频繁排查过程

      本文链接:https://www.haomeiwen.com/subject/kmiuiktx.html