Java 我在JNI代码中加密了数据,但是生成了大量内存,无法释放。我该怎么办?
我有个问题。我希望能够使用XOR+Base64编码在JNI中加密字符串。但是,我发现一些生成的本机内存没有释放,我不知道问题出现在哪里 内存配置文件如下所示: 我循环调用500000次,以便观察足够的信息 我的Java代码如下:Java 我在JNI代码中加密了数据,但是生成了大量内存,无法释放。我该怎么办?,java,android,java-native-interface,Java,Android,Java Native Interface,我有个问题。我希望能够使用XOR+Base64编码在JNI中加密字符串。但是,我发现一些生成的本机内存没有释放,我不知道问题出现在哪里 内存配置文件如下所示: 我循环调用500000次,以便观察足够的信息 我的Java代码如下: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.sample_text);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String source = "{\"page\":1,\"rows\":10,\"ucode\":\"150097\"}";
for (int i = 0; i < 500000; i++) {
String encryptStr = CCLibrary.encrypt(source);
String decryptStr = CCLibrary.decrypt(encryptStr);
}
Log.e(TAG, "completed.");
}
});
}
Java_org_pp_va_android_jniprotectedbackup_CCLibrary_decrypt(JNIEnv *env, jclass clazz,
jstring str) {
const char *rawData = env->GetStringUTFChars(str, nullptr);
int stringLength = env->GetStringUTFLength(str);
int resultLength = stringLength / 4 * 3;
if (rawData[stringLength - 1] == '=') {
resultLength -= 1;
if (rawData[stringLength - 2] == '=') {
resultLength -= 1;
}
}
char *chars = nullptr;
chars = new char[resultLength + 1];
memset(chars, 0, resultLength + 1);
chars[resultLength] = 0;
unsigned long outlen = resultLength;
int result = base64_decode((unsigned char *) rawData, stringLength, (unsigned char *) chars,
&outlen);
if (result != 0) {
memset(chars, -result, resultLength);
}
for (int i = 0; i < outlen; ++i) {
chars[i] = (chars[i] ^ XOR_API);
}
env->ReleaseStringUTFChars(str, rawData);
return env->NewStringUTF(chars);
}
JNIEXPORT jstring JNICALL
Java_org_pp_va_android_jniprotectedbackup_CCLibrary_encrypt(JNIEnv *env, jclass clazz,
jstring str) {
jsize len = env->GetStringUTFLength(str);
char *c_msg = nullptr;
c_msg = (char *) env->GetStringUTFChars(str, nullptr);
for (int i = 0; i < len; ++i) {
c_msg[i] = (c_msg[i] ^ XOR_API);
}
char *c_encoded = nullptr;
c_encoded = base64_encode(c_msg, len);
env->ReleaseStringUTFChars(str, (const char *) c_msg);
return env->NewStringUTF(c_encoded);
}
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv=findViewById(R.id.sample\u text);
tv.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
字符串源=“{\'页\':1,\'行\':10,\'ucode\':\'150097\'”;
对于(int i=0;i<500000;i++){
字符串encryptStr=CCLibrary.encrypt(源代码);
String decryptStr=CCLibrary.decrypt(encryptStr);
}
Log.e(标记“已完成”);
}
});
}
我的JNI代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.sample_text);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String source = "{\"page\":1,\"rows\":10,\"ucode\":\"150097\"}";
for (int i = 0; i < 500000; i++) {
String encryptStr = CCLibrary.encrypt(source);
String decryptStr = CCLibrary.decrypt(encryptStr);
}
Log.e(TAG, "completed.");
}
});
}
Java_org_pp_va_android_jniprotectedbackup_CCLibrary_decrypt(JNIEnv *env, jclass clazz,
jstring str) {
const char *rawData = env->GetStringUTFChars(str, nullptr);
int stringLength = env->GetStringUTFLength(str);
int resultLength = stringLength / 4 * 3;
if (rawData[stringLength - 1] == '=') {
resultLength -= 1;
if (rawData[stringLength - 2] == '=') {
resultLength -= 1;
}
}
char *chars = nullptr;
chars = new char[resultLength + 1];
memset(chars, 0, resultLength + 1);
chars[resultLength] = 0;
unsigned long outlen = resultLength;
int result = base64_decode((unsigned char *) rawData, stringLength, (unsigned char *) chars,
&outlen);
if (result != 0) {
memset(chars, -result, resultLength);
}
for (int i = 0; i < outlen; ++i) {
chars[i] = (chars[i] ^ XOR_API);
}
env->ReleaseStringUTFChars(str, rawData);
return env->NewStringUTF(chars);
}
JNIEXPORT jstring JNICALL
Java_org_pp_va_android_jniprotectedbackup_CCLibrary_encrypt(JNIEnv *env, jclass clazz,
jstring str) {
jsize len = env->GetStringUTFLength(str);
char *c_msg = nullptr;
c_msg = (char *) env->GetStringUTFChars(str, nullptr);
for (int i = 0; i < len; ++i) {
c_msg[i] = (c_msg[i] ^ XOR_API);
}
char *c_encoded = nullptr;
c_encoded = base64_encode(c_msg, len);
env->ReleaseStringUTFChars(str, (const char *) c_msg);
return env->NewStringUTF(c_encoded);
}
Java_org_pp_va_android_jniprotectedbackup_CCLibrary_decrypt(JNIEnv*env,jclass clazz,
jstring str){
const char*rawData=env->GetStringUTFChars(str,nullptr);
int stringLength=env->GetStringUTFLength(str);
int resultLength=stringLength/4*3;
如果(原始数据[stringLength-1]='='='){
结果长度-=1;
如果(原始数据[stringLength-2]='='='){
结果长度-=1;
}
}
char*chars=nullptr;
chars=新字符[resultLength+1];
memset(字符数,0,结果长度+1);
字符[结果长度]=0;
无符号长输出长度=结果长度;
int result=base64_解码((无符号字符*)原始数据,字符串长度,(无符号字符*)字符,
&奥特伦);
如果(结果!=0){
memset(字符、结果、结果长度);
}
对于(int i=0;i释放StringUTFChars(str、rawData);
返回env->NewStringUTF(chars);
}
JNIEXPORT jstring JNICALL
Java_org_pp_va_android_jniprotectedbackup_CCLibrary_encrypt(JNIEnv*env,jclass clazz,
jstring str){
jsize len=env->GetStringUTFLength(str);
char*c_msg=nullptr;
c_msg=(char*)env->GetStringUTFChars(str,nullptr);
对于(int i=0;i释放StringUTFChars(str,(const char*)c_msg);
返回env->NewStringUTF(c_编码);
}
我不确定代码哪里错了,可能是新的char[resultLength+1]或env->NewStringUTF()
你能帮我吗?我看不出你在哪里删除
字符和c_编码的?这就是内存泄漏…你是对的。我可以调用free(chars)和free(c_编码)来释放内存吗?还有其他方法可以调用吗?没有,char
是用new
分配的,因此您应该使用delete[]
c_encoded
在base64_encode
中分配-您必须查找其分配器和相应的deallocator。非常感谢您的帮助<代码>c_编码
使用malloc
分配内存。我免费发布了它。并使用delete[]
发布chars
。