I want to know how to track memory leaks in JNI with Android Profiler. I have an app using NDK and it has memory leaks in JNI. I checked it in Profiler.
JNIEXPORT jfloat JNICALL
FACE_ENGINE_METHOD(nativeExtractLiveFeature)(JNIEnv *env, jobject instance,
jobject bmp, jint left, jint top, jint right, jint bottom,
jfloatArray landmarksX, jfloatArray landmarksY, jfloatArray features)
{
cv::Mat matBGR;
ConvertBitmap2Mat(env, bmp, matBGR);
if( matBGR.empty() || matBGR.cols == 0 || matBGR.rows == 0)
return 0.0f;
LOG_DEBUG("Frame Size = (%d, %d)", matBGR.cols, matBGR.rows);
LOG_DEBUG("Face Rect = (%d, %d, %d, %d)", left, top, right, bottom);
cv::Rect rtFace;
rtFace.x = max(0, left);
rtFace.y = max(0, top);
rtFace.width = min(matBGR.cols, right) - rtFace.x;
rtFace.height = min(matBGR.rows, bottom) - rtFace.y;
Live *pLive = Live::getInstance();
float confidence = pLive->Detect(matBGR, rtFace);
LOG_DEBUG("Face Live Conf = %f", confidence);
float posLMX[5];
float posLMY[5];
jfloat* tmpLandX = env->GetFloatArrayElements(landmarksX, NULL);
jfloat* tmpLandY = env->GetFloatArrayElements(landmarksY, NULL);
for(int i = 0; i < 5; i++){
posLMX[i] = tmpLandX[i];
posLMY[i] = tmpLandY[i];
LOG_DEBUG("Landmark (x, y) = (%.2f, %.2f)", posLMX[i], posLMY[i]);
}
float feat[128];
FaceFeature *pFF = FaceFeature::getInstance();
pFF->GetFeatures(matBGR, posLMX, posLMY, feat);
LOG_DEBUG("It was finished to extract the feature");
matBGR.release();
env->SetFloatArrayRegion(features, 0, 128, (jfloat*)feat);
env->ReleaseFloatArrayElements(landmarksX, tmpLandX, 0);
env->ReleaseFloatArrayElements(landmarksY, tmpLandY, 0);
return confidence;
}
The app calls this JNI function repeatly and it causes memory leaks. I need to find solution with android Profiler.
Using the Native Memory Allocations feature in the Android Studio Profiler you can use the callstack "visualization" of the allocations and see if you are allocating multiple instances.