Java 我在JNI代码中加密了数据,但是生成了大量内存,无法释放。我该怎么办?

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

我有个问题。我希望能够使用XOR+Base64编码在JNI中加密字符串。但是,我发现一些生成的本机内存没有释放,我不知道问题出现在哪里

内存配置文件如下所示:

我循环调用500000次,以便观察足够的信息

我的Java代码如下:

@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