Android NDK 释放内存

Android NDK releasing memory

本文关键字:内存 释放 NDK Android      更新时间:2023-10-16

我有基本的 ndk 项目: NdkTest.java类和ndk.cpp文件。现在我有C++对象,应该创建一次,并在应用程序被杀死或关闭时销毁。所以我的NdkTest.java看起来像这样:

NdkTest {
    static {
        System.loadLibrary("testLib");
    }
    public static native method1();
    public static native method2();
}

ndk.cpp看起来像这样:

#include <jni.h>
extern "C" {
    void packageName_ClassName_method1(Env *, class);
    void packageName_ClassName_method2(Env *, class);
}
ManagerClass *manager = NULL; //this is actually in .h file but for simplicity of this example I put it here
void packageName_ClassName_method1(Env *env, class clazz) {
    if(manager==NULL) {
        manager = new Manager();
    }
    manager->method1();
}
void packageName_ClassName_method2(Env *env, class clazz) {
    if(manager==NULL) {
        manager = new Manager();
    }        
    manager->method2();
}

现在。。。管理器应该只创建一次,并且应该由我的所有本机方法使用。此代码将编译并工作,但它会导致内存泄漏,因为管理器永远不会被销毁。它应该在哪里销毁?当然,我可以创建像createManager()destroyManager()这样的java方法,但我不想这样做。甚至可能吗?我尝试像这样使管理器对象全局化:

ManagerClass manager;
void packageName_ClassName_method1(Env *env, class clazz) {    
    manager.method1();
}
void packageName_ClassName_method2(Env *env, class clazz) {    
    manager.method2();
}

它也可以工作,但我不知道它是否曾经被调用过析构函数。我把日志放在那里,但它从未显示过。

所以我的问题是:在 Android 原生开发中处理释放内存的最佳方法是什么?有什么好的模式吗?如果唯一的方法是创建 java 方法createManager()destroyManager()那么我应该在哪里调用 destroyManager((?Java finalize(( 不能保证被调用,所以我应该把它放在哪里?


我找到了关于这个主题的精彩视频:

  • https://www.youtube.com/watch?v=KTC0g14ImPc

大约31分钟是最好的部分:)

使用 Android 内存管理模型,无法保证会调用任何析构函数。本书对你唯一的保证是,将为前台活动调用onPause()方法。

OTOH,Linux 内核负责释放被优雅或强制关闭的进程使用的所有资源。

因此,除非你的单例锁定了一些非常特殊的系统资源,而这些资源不能被内核自动回收,否则你不必担心它的析构函数。但是,如果确实如此(例如,它锁定了相机(,则需要一种防弹机制来尽早解锁此资源,最好是onPause()

所有这些讨论都不适用于单例的创建。您可以使用上面描述的任何方法,并选择最适合您的体系结构的方法。仅请记住应用销毁序列可能在创建 Manager 对象时启动的争用情况(仅在多线程方案中可能(。