如何解决Java和C
我有一个Java应用程序,该应用程序使用C库从相机获取帧。我正在做的是将帧数据存储在c库中,然后将元数据传递给Java。然后从Java通过JNI调用该相机的最新帧数据。
我遇到的问题是,在这些功能之一中,我似乎有内存泄漏。处理开始后,它会在几秒钟内飙升到几GB。但是,如果我运行C库以独立运行(基本上是完全相同的代码,只是没有JNI组件),就不会发生内存泄漏。
这是两个C函数:
JNIEXPORT jbyteArray JNICALL
Java_com_c_C_1Wrapper_nGet_1Image (JNIEnv *env,jobject jobj,jint i_) {
_jobj = jobj;
jint rs = (*env)->GetJavaVM(env,&jvm);
assert (rs == JNI_OK);
jbyteArray img_data;
int cam_id = i_;
if (!frame_data[cam_id].lock) {
frame_data[cam_id].lock = TRUE;
img_data = (*env)->NewByteArray(env,frame_data[cam_id].data_size);
(*env)->SetByteArrayRegion(env,img_data,frame_data[cam_id].data_size,(jbyte*)frame_data[cam_id].img);
frame_data[cam_id].lock = FALSE;
}
return img_data;
}
void
send_frame_data(guint camera_id,gint data_size,void *new_frame,gint width,gint height,const char *meta_data) {
JNIEnv *env;
jint rs = (*jvm)->AttachCurrentThread(jvm,&env,NULL);
assert (rs == JNI_OK);
if (!frame_data[camera_id].lock) {
frame_data[camera_id].lock = TRUE;
free(frame_data[camera_id].img);
frame_data[camera_id].img = malloc(data_size);
memcpy(frame_data[camera_id].img,new_frame,data_size);
frame_data[camera_id].width = width;
frame_data[camera_id].height = height;
frame_data[camera_id].data_size = data_size;
frame_data[camera_id].lock = FALSE;
}
jbyteArray jMetaData = (*env)->NewByteArray(env,strlen(meta_data));
(*env)->SetByteArrayRegion(env,jMetaData,strlen(meta_data),meta_data);
(*env)->CallStaticVoidMethod(env,jSentryCore_class,jImagePreview,jMetaData);
(*env)->DeleteLocalRef(env,jMetaData);
}
值得注意的是,* new_frame对象已从调用方法中释放。
Java方面很简单:
@Override
public void ImagePreview(String metaData) {
// parse metaData
byte[] image = C_Wrapper.Get_Image(cameraId);
// do something with data
}
我没有好运就重新安排了几次逻辑。无论我做什么,只要JNI部分在播放中,就会出现严重的内存泄漏。
解决方法
这不是内存泄漏,您分配内存的速度超过了Java垃圾回收器释放内存的速度。假设1080p @ 60和16bpp,即250 MB / s。 C可以处理它,因为如果大小相等,malloc
很可能会free
退还给您。
每次NewByteArray
的调用都应停止调用Get_Image
。相反,请保留byte[]
个对象的固定大小的池,并更改Get_Image
以从池中获取缓冲区。完成Java代码后,您还需要将缓冲区返回到池中。根据Java代码对图像的处理方式,还可以改为使用直接ByteBuffer
来进行调查:您可以从C直接编写这些内容,而不必调用memcpy
。
这会将您的内存上限限制为缓冲区的数量。请记住,当您调用Get_Image并找出处理它的策略时,当前可能没有缓冲区可用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。