jni Java_com_sgx_jni_RaISVNative_decryptAndSealingPartData2 memory leak

本文深入探讨了Java Native Interface (JNI) 中的内存管理问题,特别是针对byte数组操作时的常见错误与正确实践。通过对比分析三段代码,揭示了如何避免内存泄漏,确保JNI函数在获取和释放本地字节缓冲区时的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. The following code does not release memory correctly.
JNIEXPORT void JNICALL Java_com_baidu_dragonshare_sgx_jni_RaISVNative_decryptAndSealingPartData2
  (JNIEnv *env, jobject thisObj, jobject j_enclaveId,
		  jbyteArray j_buffer, jint j_size, jint j_start_index
		  , jobject sealed_result, jbyteArray j_sealed_buffer){
	//	fprintf(stdout, "ISV JNI ==> , j_size=%d,j_start_index=%d\n",j_size ,j_start_index);

		// Get the elements (you probably have to fetch the length of the array as well
		jbyte * buffer = env->GetByteArrayElements(j_buffer, NULL);
		jsize buffer_length = env->GetArrayLength(j_buffer);

	//	fprintf(stdout, "ISV JNI ==> After GetByteArrayElements , buffer_length=%d\n",buffer_length);

		uint32_t size = j_size;
		uint32_t start_index = j_start_index;

	//	fprintf(stdout, "ISV JNI ==> init encrypted_data, length=%d\n",buffer_length);

		// construct byte_array_buffer struct and init with #byte_array_buffer
		byte_array_buffer*  encrypted_buffer = init_byte_array_buffer(buffer_length);
		for (jint i = 0; i < buffer_length; i++) {
			encrypted_buffer->data[i] = buffer[i];
		}
		encrypted_buffer -> size = size;

		free(encrypted_buffer->data);
		free(encrypted_buffer);


}
  1. The following code does not work correctly.
// Get the elements (you probably have to fetch the length of the array as well
		jbyte * buffer = env->GetByteArrayElements(j_buffer, NULL);
		jsize buffer_length = env->GetArrayLength(j_buffer);

	//	fprintf(stdout, "ISV JNI ==> After GetByteArrayElements , buffer_length=%d\n",buffer_length);

		uint32_t size = j_size;
		uint32_t start_index = j_start_index;

3.The following code works correctly.

JNIEXPORT void JNICALL Java_com_baidu_dragonshare_sgx_jni_RaISVNative_decryptAndSealingPartData2
  (JNIEnv *env, jobject thisObj, jobject j_enclaveId,
		  jbyteArray j_buffer, jint j_size, jint j_start_index
		  , jobject sealed_result, jbyteArray j_sealed_buffer){
	//	fprintf(stdout, "ISV JNI ==> , j_size=%d,j_start_index=%d\n",j_size ,j_start_index);

		// Get the elements (you probably have to fetch the length of the array as well
		jbyte * buffer = env->GetByteArrayElements(j_buffer, NULL);
		jsize buffer_length = env->GetArrayLength(j_buffer);

	//	fprintf(stdout, "ISV JNI ==> After GetByteArrayElements , buffer_length=%d\n",buffer_length);

		uint32_t size = j_size;
		uint32_t start_index = j_start_index;

	//	fprintf(stdout, "ISV JNI ==> init encrypted_data, length=%d\n",buffer_length);

		// construct byte_array_buffer struct and init with #byte_array_buffer
		env->ReleaseByteArrayElements(j_buffer, buffer, JNI_ABORT);
}
  1. test jni call java object, no memory leak problem, loop times 1000 * 1000 * 1000
JNIEXPORT void JNICALL Java_com_baidu_dragonshare_sgx_jni_RaISVNative_decryptAndSealingPartData3
  (JNIEnv *env, jobject thisObj, jobject j_enclaveId,
		  jbyteArray j_buffer, jint j_size, jint j_start_index
		  , jobject sealed_result, jbyteArray j_sealed_buffer){

		jbyte * buffer = env->GetByteArrayElements(j_buffer, NULL);
		jsize buffer_length = env->GetArrayLength(j_buffer);
		uint32_t size = j_size;
		uint32_t start_index = j_start_index;
		env->ReleaseByteArrayElements(j_buffer, buffer, JNI_ABORT);
}
  1. no memory leak, loop times:10000000
JNIEXPORT void JNICALL Java_com_baidu_dragonshare_sgx_jni_RaISVNative_decryptAndSealingPartData2
  (JNIEnv *env, jobject thisObj, jobject j_enclaveId,
		  jbyteArray j_buffer, jint j_size, jint j_start_index
		  , jobject sealed_result, jbyteArray j_sealed_buffer){
	//	fprintf(stdout, "ISV JNI ==> , j_size=%d,j_start_index=%d\n",j_size ,j_start_index);

		// Get the elements (you probably have to fetch the length of the array as well
		jbyte * buffer = env->GetByteArrayElements(j_buffer, NULL);
		jsize buffer_length = env->GetArrayLength(j_buffer);

	//	fprintf(stdout, "ISV JNI ==> After GetByteArrayElements , buffer_length=%d\n",buffer_length);

		uint32_t size = j_size;
		uint32_t start_index = j_start_index;

	//	fprintf(stdout, "ISV JNI ==> init encrypted_data, length=%d\n",buffer_length);

		// construct byte_array_buffer struct and init with #byte_array_buffer
		byte_array_buffer*  encrypted_buffer = init_byte_array_buffer(buffer_length);
		for (jint i = 0; i < buffer_length; i++) {
			encrypted_buffer->data[i] = buffer[i];
		}
		encrypted_buffer -> size = size;
	//	fprintf(stdout, "ISV JNI ==> After init_byte_array_buffer, size=%d\n",size);

		int capacity = getIntField(env, sealed_result, "threshold");
	//	fprintf(stdout, "ISV JNI ==> After get threshold=%d\n", capacity);

		byte_array_buffer* sealed_buffer = init_byte_array_buffer(capacity);

		sgx_enclave_id_t enclave_id = getLongField(env, j_enclaveId, "enclaveId");
		sgx_status_t status = SGX_SUCCESS;
		uint32_t sealed_data_size;
		sgx_ra_context_t context;

		decrypt_and_sealing_partial_data(enclave_id, &status, (uint8_t*)encrypted_buffer, buffer_length,
				size, start_index, (uint8_t*)sealed_buffer,
				capacity, &sealed_data_size, capacity, &context);

		// setByteArray(env, sealed_buffer -> data, capacity, sealed_result, "sealedBuffer");
		env->SetIntField(sealed_result, getFid(env, sealed_result, "size", "I"), sealed_data_size);
		env->SetIntField(sealed_result, getFid(env, sealed_result, "context", "I"), context);

		// setByteArray(env, sealed_buffer->data, capacity, sealed_result, "sealed_buffer");

		// free sealed_buffer
		free(sealed_buffer->data);
		free(sealed_buffer);
		free(encrypted_buffer->data);
		free(encrypted_buffer);
		env->ReleaseByteArrayElements(j_buffer, buffer, JNI_ABORT);


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值