我在Java中使用OpenCV,因为OpenCV不知道Java GC在做什么,所以我总是被告知我需要使用Mat.release()释放我的Mat个对象,以避免内存泄漏.因此,我一直在使用try—finally:

// Suppose this is actually reading some image or similar
Mat mat = new Mat()

try {
    // Do something with mat
} finally {
    mat.release()
}

在调试一个内存泄漏(我还没有找到原因)时,我查看了生成的Mat.java源代码,发现了以下内容:

public class Mat {
    // ...
    
    public void release() {
        n_release(nativeObj);
    }

    // ...
    
    @Override
    protected void finalize() throws Throwable {
        n_delete(nativeObj);
        super.finalize();
    }

    // ...

因此,总的来说,release内部呼叫n_releasefinalize内部呼叫n_delete.无论调用的方法是什么,在方法调用之后,Mat.dataAddr()都返回0L.

作为一个非C++开发人员,我的问题如下:

  • n_releasen_delete有什么区别?
  • n_delete实际上释放了与Mat相关的内存,还是仅仅删除指向它的指针?
  • 我真的需要显式调用Mat.release(),还是调用finalize()(由垃圾收集器隐式完成)足够?

编辑: 在调试内存泄漏时,我也看了一下Core.merge(),看起来像这样:

public static void merge(List<Mat> mv, Mat dst) {
    Mat mv_mat = Converters.vector_Mat_to_Mat(mv);
    merge_0(mv_mat.nativeObj, dst.nativeObj);
}

它创建了一个临时的Mat对象(称为mv_mat),它从不调用release(),因为mv_mat是方法的内部,所以没有外部调用者可以调用mv_mat.release().因此,我假设忘记调用release()而不被推荐(由于依赖终结器)本身并不构成内存泄漏.

推荐答案

n_release和n_edit的区别: n_release递减引用计数,如果没有引用剩余,则释放资源. 当Java对象被垃圾回收时,n_Delete直接释放内存.

n_删除空闲内存吗?: 是的,n_edit被设计为释放分配的本地内存,而不仅仅是删除指针.

是否需要显式调用Mat. release()? 是的,您应该显式调用Mat. release()来有效地管理内存.依赖finalize()是不可取的,因为它的不可预测性和潜在的资源释放延迟.使用Mat.release()显式释放资源确保了及时的内存管理并避免了内存泄漏.

Java相关问答推荐

PostgreSQL货币兑换率查询

如何在SystemiccationRetryListenerSupport中获得类级别的spring retryable annotation中指定的标签?

Jooq外键关系

Jlink选项&-strie-ative-Commands";的作用是什么?

我需要生成一个文件来整合每个特性执行的所有JSON结果

我找不到&Quot;配置&的位置

SpringBoot+Java 17@Valid未验证POJO

无法在Java中处理PayPal支付响应

如何在JavaFX中处理多个按钮

在添加AdMob时无法为Google Play构建应用程序包:JVM垃圾收集器崩溃和JVM内存耗尽

将PNG转换为位图自定义十六进制字符串

使用While循环打印素数,无法正常工作

S数学.exp的相同错误保证也适用于StrictMath.exp吗?

为了安全起见,有必要复制一份 list 吗?

在缺少字段时使用Jackson With Options生成Optional.Empty()

RestTemplate Bean提供OkHttp3ClientHttpRequestFactory不支持Spring Boot 3中的请求正文缓冲

Java HashMap保留所有时间复杂性

无限递归Java问题

控制器建议异常处理

为什么Java编译器为没有参数的方法(getter方法)创建桥接方法