java多线程内存回收探索

背景

最近项目上遇到个问题,采用多线程处理的时候发现子线程内部处理不够快,主线程生产子线程需要处理的批次数据,主线程生产数据快,导致主线程产生的数据得不到子线程及时处理,内存快速被撑爆,触发fullgc,又导致大量cpu被用于处理gc,子线程处理起来更慢了,原来1秒处理一批次,到后来10分钟处理一批次。

探索

写个测试代码复现一下,顺便也验证一下子线程处理完成后,被子线程占有的需要处理的数据对象会自动被jvm垃圾收集器 自动回收,内存不会持续暴涨。

验证点1

子线程处理完成后,持有的需要处理的数据对象会被jvm自动回收。

验证点2

子线程处理慢,处理速度小于主线程产生数据的速度,内存积压,内存持续上涨,最终把内存干满,频繁触发fullgc,子线程处理速度持续降低,持续恶化。

模拟方式,子线程休眠1s后处理。

验证点3

子线程处理慢,处理速度小于主线程产生数据的速度,启用反压机制,等待子线程一批次处理完成后,主线程再继续产生数据,进入下一批次处理,已经处理完成的数据对象jvm会自行回收,新产生的数据对象能够得到处理,不会持续积压。

java 复制代码
Future future = thd4c(list1);
list1 = new ArrayList<>();
futureList.add(future);

if (futureList.size() >= maxPoolSize) {
    for (Future fr : futureList) {
        try {
            fr.get();//同步等待子线程处理完成
        } catch (Exception e) {
            logger.warn("future get error ,", e);
        }
    }
    logger.info("batch exec num: {}", ++batchNum);
}

解决方案

开多线程处理的时候,等待当前批次的几个线程处理完成,当前批次的几个子线程处理完成后再继续生产下一批次需要处理的线程,避免子线程处理不及时的时候,在内存堆积大量需要处理的数据。

相关推荐
微风中的麦穗5 小时前
【MATLAB】MATLAB R2025a 详细下载安装图文指南:下一代科学计算与工程仿真平台
开发语言·matlab·开发工具·工程仿真·matlab r2025a·matlab r2025·科学计算与工程仿真
2601_949146535 小时前
C语言语音通知API示例代码:基于标准C的语音接口开发与底层调用实践
c语言·开发语言
开源技术5 小时前
Python Pillow 优化,打开和保存速度最快提高14倍
开发语言·python·pillow
学嵌入式的小杨同学5 小时前
从零打造 Linux 终端 MP3 播放器!用 C 语言实现音乐自由
linux·c语言·开发语言·前端·vscode·ci/cd·vim
毕设源码-朱学姐6 小时前
【开题答辩全过程】以 基于JavaWeb的网上家具商城设计与实现为例,包含答辩的问题和答案
java
mftang7 小时前
Python 字符串拼接成字节详解
开发语言·python
jasligea7 小时前
构建个人智能助手
开发语言·python·自然语言处理
kokunka7 小时前
【源码+注释】纯C++小游戏开发之射击小球游戏
开发语言·c++·游戏
C雨后彩虹7 小时前
CAS与其他并发方案的对比及面试常见问题
java·面试·cas·同步·异步·
云栖梦泽8 小时前
易语言开发从入门到精通:补充篇·网络编程进阶+实用爬虫开发·API集成·代理IP配置·异步请求·防封禁优化
开发语言