Java androidndk释放内存

Java androidndk释放内存,java,android,c++,memory,android-ndk,Java,Android,C++,Memory,Android Ndk,我有基本的ndk项目: NdkTest.java < /Cord>类和 NDK.CPP文件。现在我有一个C++对象,应该创建一次,在应用程序被关闭或关闭时销毁。 因此,我的NdkTest.java如下所示: NdkTest { static { System.loadLibrary("testLib"); } public static native method1(); public static native method2(); } #i

我有基本的ndk项目: <代码> NdkTest.java < /Cord>类和 NDK.CPP文件。现在我有一个C++对象,应该创建一次,在应用程序被关闭或关闭时销毁。 因此,我的
NdkTest.java
如下所示:

NdkTest {
    static {
        System.loadLibrary("testLib");
    }
    public static native method1();
    public static native method2();
}
#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();
}
ManagerClass manager;

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

void packageName_ClassName_method2(Env *env, class clazz) {    
    manager.method2();
}
ndk.cpp
如下所示:

NdkTest {
    static {
        System.loadLibrary("testLib");
    }
    public static native method1();
    public static native method2();
}
#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();
}
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分钟。最好的部分是:)

对于Android模式的内存管理,不能保证会调用任何析构函数。这本书唯一能保证的是前台活动将调用
onPause()
方法

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

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


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

所以你是说我可以使用
new
创建它,而不使用
delete
离开,系统会关心释放内存吗?我的类没有使用任何与Android相关的东西。我只在C++中写了一些高效的算法。是的,你可以忽略删除部分,但是要记住两个场景:确保你再也不需要重新创建管理器(例如,你的应用程序被关闭并再次打开,但是系统决定了该过程可以被重用),并且如果你使用工具来查找内存泄漏,他们会抱怨的。他们不关心Android进程管理的极端情况,所以他们会对最天真的
delete
感到满意。多么奇怪的评论。在C++中,你不能关心你分配的内存。当你不再需要它时,你必须把它处理掉。所以说te OP不应该关心这些事情是错误的。当然,在“应用程序被杀死”的背景下,这并不重要。但是,您仍然应该关心资源分配/释放。你不能说:“啊,是的,我们的图书馆应该被操作系统杀死”之类的话。@WernerVanBelle,我很抱歉。对纯粹主义者来说,现实有时是痛苦的。您可能会说,一般来说全局变量,特别是单例模式是不好的做法,但语言确实允许这些,运行时环境负责销毁这些变量。在Android上,在
JNI_OnLoad()
上创建的对象实际上相当于全局变量,因为我们可能永远无法控制它们的破坏。Java
finalize()
方法也是如此:您不应该依赖于所有的
finalize()
方法被调用,或者以特定的顺序被调用。@AlexCohn当然,这可能是Java中的方式。这并不能改变这样一个事实,如果你写C++,你必须注意你的记忆力。让操作系统清理你的烂摊子是没有选择的。此外,至少可以清理java代码的终结方法中的C++资源,否则会泄漏内存。