Java 执行 JVM Native 方法导致内存碎片

news/2024/9/24 6:18:01/

背景🚞

由于需要调用到 C/C++ 的业务对外,使用了 Java 来封装 SDK 进行调用。
事故起因⚡:当 Java 使用 JNI 发生调用 JVM Native 本地方法时,发现内存一直飙升发生 OOM。

操作复现🔍

使用 Jmeter 进行压测高并发环境
1)当 Java 调用 C 时开辟一段内存空间,紧接着再次调用 C 释放内存空间,内存正常。
2)当 Java 调用 C 时开辟一段内存空间时,不进行释放,待多线程开辟大量内存空间,再度批量释放(批量释放的代码就是 for 循环调用 C 提供的方法释放,跟情况 1 释放方法逻辑一致)
发现第二种方法内存释放完后依旧不降,内存无法释放的情况,发生 OOM。

参考帖子📑:

1)https://segmentfault.com/a/1190000042015931?sort=newest

2)https://juejin.cn/post/7255634554987020343#heading-19

3)https://juejin.cn/post/7241395886856880165

最终排查得出🔥

是 Linux 操作系统默认使用的内存分配器是 ptmalloc2,该内存分配器内部有一个内存池,ptmalloc2 在高并发分配内存时,会存在较多内存碎片无法释放的情况,碎片积压到一定程度甚至会导致进程内存不够用,最终OOM。

解决方法🍑

替换内存分配器为 google 的 tcmalloc 或 facebook 的 jemalloc

将内存分配器的库打包到项目部署包中,再用 export LD_PRELOAD 指定函数库

Dockerfile 编写💡

RUN yum upgrade -y; yum group install -y "Development Tools"; \yum install -y wget tcl which zlib-devel git docbook-xsl libxslt graphviz; \yum clean all
RUN mkdir -p /opt && cd /opt && git clone https://github.com/jemalloc/jemalloc.git \&& mkdir /tmp/jprof && mkdir /tmp/nmt && mkdir /tmp/pmap \&& mkdir /diagnosticRUN cd /opt/jemalloc && git checkout -b stable-4 origin/stable-4
RUN cd /opt/jemalloc && ./autogen.sh --enable-prof
RUN cd /opt/jemalloc && make dist
RUN cd /opt/jemalloc && make
RUN cd /opt/jemalloc && make installENV LD_PRELOAD="/usr/local/lib/libjemalloc.so"
ENV MALLOC_CONF="prof_leak:true,prof:true,lg_prof_interval:25,lg_prof_sample:18,prof_prefix:/tmp/jeprof"

http://www.ppmy.cn/news/1438288.html

相关文章

isListEqual方法比较

这个方法有改进空间吗&#xff1f; private static boolean isListEqual(List<String> l0, List<String> l1) {if (l0 null && l1 null)return true;if (l0 l1)return true;if (l0 null || l1 null)return false;if (l0.size() ! l1.size())return f…

Redis服务

参考文章&#xff1a; Win.dow.s上安装Redis教程 redis数据库基础篇 Redis 的安装及图形化界面 Redis DeskTop Manager 的安装与使用 下载Redis Redis压缩包 打开Redis 法1&#xff1a; 双击redis-server.exe 应用程序 法2&#xff1a; 进入redis目录下&#xff0c;打cmd…

Entity FrameWork EF 加载方式

1》》 立即加载 2》》 延迟加载 EF 默认加载模式 3》》显示加载

华为机试:夺宝奇兵

夺宝奇兵 | 时间限制&#xff1a;1秒 | 内存限制&#xff1a;262144K 一个3人寻宝团队搜寻沉船成功&#xff0c;获得一笔宝藏&#xff0c;领头人为不起纷争&#xff0c;决定将财宝分成3N份&#xff0c;每次3人从分好的3堆宝藏中依次拿取&#xff0c;领头人第一拿&#xff0c;你…

ubuntu16安装docker及docker-compose

ubuntu16安装docker及docker-compose 一、环境前期准备 检查系统版本 系统版本最好在16及以上&#xff0c;可以确保系统的兼容性 lsb_release -a查看内核版本及系统架构 建议用 x86_64的系统架构&#xff0c;安装是比较顺利的 uname -a32的系统不支持docker&#xff0c;安…

我们真的需要Chinese-LLaMA3本地大模型吗

LLaMA3 8B版本的表现已经能和GPT-4还有Claude3这些大佬一较高下了&#xff01;想象一下70B版本得有多牛&#xff0c;是不是得飞上天和太阳肩并肩了&#xff1f; 不过&#xff0c;原版的LLaMA3主要是用英文世界的语料喂大的&#xff0c;虽然它对中文也能点头哈腰&#xff0c;但因…

EJB和Spring

1. EJB 1.1. 背景 功能日趋复杂的软件&#xff0c;如果把所有的功能实现都放在客户端&#xff0c;不仅代码没有安全性&#xff0c;部署及发布运维都会变的很复杂&#xff0c;所以将软件的功能实现分为客户端和服务端&#xff0c;服务端和客户端之间通过网络调用进行功能实现。…

vue使用海康控件开发包——浏览器直接查看海康监控画面

1、下载控件开发包 2、安装插件&#xff08;双击/demo/codebase/HCWebSDKPlugin.exe进行安装&#xff09; 3、打开/demo/index.html文件 4、在页面上输入你的海康监控的登录信息进行预览 如果有监控画面则可以进行下面的操作 注意&#xff1a;以下操作都在Vue项目进行 5、复…