关于jni如何才能不泄露内存的基本原则:
- c/c++分配的资源,一律需要自己管理(可以用智能指针管理起来,或者用RAII思想管理),否则一定会存在内存泄漏
- jni api分配的资源,若是c/c++类型,需要自己管理,因为这些变量分配在jni heap上,java不会帮你管理。若是java类型(jstring/jobject等各种j开头的类型),这些变量分配在java heap上,java的GC会帮你回收。
我本次的内存泄漏是上述第2点导致,即,我通过GetStringUTFChars
从jstring得到char*,最后没有去释放c/c++的char*,导致了内存泄漏。随后我使用ReleaseStringUTFChars
释放该对象后,内存泄漏现象消失。
总之,jni层,申请资源/释放资源需要一一匹配,否则就很可能会导致内存泄漏。
jni的很多api都是成对出现,如GetStringUTFChars
和ReleaseStringUTFChars
等等,在函数返回之前,一定要及时释放申请的资源(可用RAII手段轻松做到)。
具体的需要成对调用的jni api可参考下面的链接。
注意:不能重复多次释放资源(例如多次对同一对象调用ReleaseStringUTFChars
),否则程序会crash