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

背景🚞

由于需要调用到 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 编写💡

bash 复制代码
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 /diagnostic

RUN 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 install

ENV 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"
相关推荐
嵌入小生0074 分钟前
Standard IO -- Continuation of Core Function Interfaces (Embedded Linux)
linux·vim·嵌入式·标准io·vscode
知识即是力量ol5 分钟前
初识 Kafka(一):分布式流平台的定义、核心优势与架构全景
java·分布式·kafka·消息队列
Zach_yuan6 分钟前
传输层之TCP/UDP 核心原理全解析:从协议基础到实战机制
linux·网络协议·tcp/ip·udp
独自归家的兔7 分钟前
Ubuntu 系统 systemd timers 详解:替代 crontab 的定时任务进阶方案
linux·运维·ubuntu
Lsir10110_8 分钟前
【Linux】深入解剖页表——分页式存储
linux·运维·服务器
爱吃生蚝的于勒9 分钟前
【Linux】线程概念(一)
java·linux·运维·服务器·开发语言·数据结构·vim
kong790692811 分钟前
Nginx性能优化
java·nginx·性能优化
Pluchon11 分钟前
硅基计划4.0 算法 简单模拟实现位图&布隆过滤器
java·大数据·开发语言·数据结构·算法·哈希算法
我命由我1234512 分钟前
Java 泛型 - Java 泛型通配符(上界通配符、下界通配符、无界通配符、PECS 原则)
java·开发语言·后端·java-ee·intellij-idea·idea·intellij idea
Seven9712 分钟前
AQS深度探索:以ReentrantLock看Java并发编程的高效实现
java