服务器内存告急?一招解决模型推理的内存泄漏!

📘 开发记录 · 07-03 · 96 人浏览
服务器内存告急?一招解决模型推理的内存泄漏!

摘要

今天在巡检服务器时,意外发现模型预测占用了惊人的16GB内存!赶紧检查代码,发现每次模型推理都会悄悄增加约200MB的内存占用。经过一番排查,终于找到了问题的根源,并给出了解决方案。

2024-07-03T09:25:29.png

发现问题

早上的服务器巡检真是让人心惊胆战,竟然发现模型推理的内存占用飙升至16GB!我立刻着手检查代码,发现每次推理时内存都会稳定增长约200MB。经过仔细分析,问题似乎出在这段代码上:

// 加载ONNX运行环境和模型
OrtEnvironment environment = OrtEnvironment.getEnvironment();
// 创建会话选项
OrtSession.SessionOptions sessionOptions = new OrtSession.SessionOptions();
// 根据模型路径创建会话
OrtSession session = CommonService.getSession(environment, CommonConstant.YOLO_MODEL_PATH, sessionOptions);

每次推理,session都会重新加载,而模型文件的大小恰好是200MB左右。

解决方案

找到了问题的根源,接下来就是解决问题的时候了。这里有几点需要考虑:

  • 资源管理:确保不再需要OrtSession时,及时关闭它,释放资源。
  • 线程安全:如果多个线程可能会访问这个全局session,确保创建过程是线程安全的。
  • 单例模式:如果希望session作为单例存在,需要实现单例模式。
  • 异常处理:在使用session时,考虑异常处理,确保资源正确清理。
  • 应用程序生命周期:根据应用程序的需求,可能需要重新加载模型或创建新的OrtSession

下面是优化后的代码示例:

public class OrtSessionManager {
    private static volatile OrtSession session;

    public static OrtSession getSession(OrtEnvironment environment, String modelPath, OrtSession.SessionOptions sessionOptions) {
        if (session == null) {
            synchronized (OrtSessionManager.class) {
                if (session == null) {
                    session = environment.createSession(modelPath, sessionOptions);
                }
            }
        }
        return session;
    }

    public static void closeSession() {
        if (session != null) {
            session.close();
            session = null; // 释放资源,让垃圾收集器可以回收
        }
    }
}

使用时,只需这样调用:

// 获取会话
OrtSession session = OrtSessionManager.getSession(environment, CommonConstant.YOLO_MODEL_PATH, sessionOptions);

// 使用会话进行操作...

// 应用程序结束或不再需要会话时,关闭会话
OrtSessionManager.closeSession();

结语

问题解决啦!内存占用得到了有效控制,再也不用担心服务器撑爆了。撒花庆祝🎉 ★,°:.☆( ̄▽ ̄)/$:.°★


onnxruntime
  1. 冰冰 28 天前

    收藏了,以后可能会用到 http://bkzh.cc

Under CC BY NC-SA License.
Powered by Typecho | Theme by Jasmine
您是第 5399 位访客