多线程下的OOM问题

前言

最近的一台服务器出现了OOM的情况,出于好奇就进行了一些探查,这里做一些简单的记录

问题排查

日志查看

登陆服务器查看当天的报错日志,根据服务器的错误日志定位到了代码,发现是一个定时任务引起的,发现该定时任务报错的同时还有一个线程也在打印错误信息。所以想到了两个可能的问题:

  1. 新增的定时任务冲突,导致多个线程同时跑任务,导致最后OOM
  2. 源代码就有问题,数据量增多导致的定时任务出现的问题

代码查看

根据代码可以发现没有大对象的存在,最大的对象也只是几千万的Long对象,但是哪怕1亿的Long对象 也不会导致OOM,所以排出了代码问题。

集群查看

由于是分布式定时任务,也就是说定时任务是随机分发的,先对该任务的执行历史进行查看,发现执行的历史记录发现同一台机器,前一天失败了,但是后一天却成功了,而其他的所有机器都是成功的。也就是可以确定源代码应该没有问题。
在这里插入图片描述
所以怀疑是问题一导致的OOM,该服务器的JVM参数没同步,即可能数据量增多之后,其他的服务器都进行了扩容,但是该服务器忘记扩容导致的,故先去集群的监控中心查看其他的服务器的堆内存大小,发现确实该服务器的内存只有8G,而其他的服务器都已经扩容到了12G。再根据其他的禁用的服务器,发现都是8G。

问题解决

机器申请扩容最后成功解决问题

多线程OOM时候的回收

上面说在查看服务器的错误日志的时候,发现一个任务的所有线程都OOM了,但是另一个定时任务的线程没有立即结束,还在运行并进行日志的打印。故进行了简单测试,查看当多线程的情况下某个线程OOM之后会发生什么?怎么样才会彻底OOM直接宕机?

测试代码

public class OutOfMemoryTest {

    public static void main(String[] args) {
        new Thread(() -> {
            List<byte[]> list = new ArrayList<>();
            while (true) {
                list.add(new byte[1024 * 1024 * 50]);
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(1_000);
                } catch (Exception e) {
                }
            }
        }, "dead thread").start();

        new Thread(() -> {
            while (true) {
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(1_000);
                } catch (Exception e) {
                }
            }
        }, "alive thread").start();
    }
}

启动参数设置

-Xmx10m -Xms10m 设置堆大小为10m

控制台打印

根据控制台的打印可以发现在多线程的情况下,如果某个线程导致了OOM,虚拟机会终止该线程并回收它所占用的资源。但是,如果OOM是由于整个应用程序使用的内存超过了虚拟机的最大内存限制而导致的,那么整个虚拟机将会崩溃。

即当应用程序使用的内存超过了虚拟机的最大内存限制时,虚拟机会抛出OutOfMemoryError异常。如果该异常没有被捕获并处理,那么虚拟机将会崩溃,并且应用程序将无法继续执行。

因此,在编写多线程应用程序时,需要注意内存的使用情况,并且及时处理OutOfMemoryError异常,以避免整个虚拟机崩溃。
在这里插入图片描述
这个就好像是操作系统的资源分配一样,如果出现了资源的长时间持有,导致了可能死锁的发生,就允许剥夺该线程资源进行资源重分配。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当单台Mac进行压测时,如果压测客户端Jmeter启动超过2000个线程,而Jmeter报OOM(Out of Memory)错误,有一些解决方法可以尝试。 首先,你可以尝试增加Jmeter的内存限制。可以通过编辑Jmeter的启动脚本来指定更大的堆内存大小,即增加-Xmx参数的值。例如,将-Xmx2g修改为-Xmx4g,表示将堆内存限制增加到4GB。 其次,你可以调整Jmeter的线程配置。在Jmeter中,每个线程都会消耗一定的内存资源。如果单台Mac的内存无法满足启动2000个线程的需求,可以考虑减少线程数,或者将压测任务分散到多台机器上进行。 另外,你也可以检查是否有其他资源导致内存不足。例如,Jmeter执行过程中可能会产生大量的日志文件,如果磁盘空间不足,也会导致OOM错误。此时,可以清理或增加磁盘空间。 最后,你可以使用Jmeter插件来优化压测性能。例如,引用中提到的自行开发的RocketMQ插件可以帮助更好地进行RocketMQ的压测。使用合适的插件可以提高效率,减少资源消耗。 综上所述,为了解决Jmeter压测时发生OOM错误的问题,你可以尝试增加Jmeter的内存限制、调整线程配置、检查其他资源是否充足,以及使用合适的插件来优化压测性能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [7个常见的Jmeter压测问题总结](https://blog.csdn.net/okcross0/article/details/129148522)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Jmeter压测问题](https://blog.csdn.net/weixin_44370919/article/details/108864324)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [jmeter压测RocketMQ的插件](https://download.csdn.net/download/weixin_40126600/85011909)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值