Android NDK释放内存

时间:2014-04-27 17:30:01

标签: java android c++ memory android-ndk

我有基本的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方法,但我不想这样做。它甚至可能吗? 我尝试将Manager对象全局化为:

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()不被保证被调用,所以我应该把它放在哪里?


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

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

1 个答案:

答案 0 :(得分:1)

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

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

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

所有这些讨论都不适用于创建Singleton。您可以使用上述任何方法,并选择最适合您的体系结构的方法。只有当仍然在创建Manager对象时才开始应用程序销毁序列的竞争情况(仅在多线程场景中)。