QiuYucheng2003 opened a new issue, #4403: URL: https://github.com/apache/carbondata/issues/4403
## Summary `sdk/CSDK/src/Configuration.cpp` leaks JNI local references. CSDK takes a caller-supplied `JNIEnv*` (typically after `JNI_CreateJavaVM` / `AttachCurrentThread`). Local refs on that thread are **not** freed when a C++ function returns. `get`/`set` never delete the `NewStringUTF` arguments; the constructor keeps `FindClass` / `NewObject` results as member fields without promoting them to global refs, and there is no destructor. ## Affected code [`sdk/CSDK/src/Configuration.cpp`](https://github.com/apache/carbondata/blob/f86ac085ddbbd8381b0a5b65658731fe618eff4a/sdk/CSDK/src/Configuration.cpp) ## 1. `get` / `set` — `jstring` arguments never released (main leak) ```cpp jvalue args[2]; args[0].l = jniEnv->NewStringUTF(key); args[1].l = jniEnv->NewStringUTF(value); jniEnv->CallObjectMethodA(configurationObject, setID, args); // args[0].l and args[1].l never DeleteLocalRef'd get only deletes the return value: jobject result = jniEnv->CallObjectMethodA(configurationObject, getID, args); char *str = (char *) jniEnv->GetStringUTFChars((jstring) result, JNI_FALSE); jniEnv->DeleteLocalRef(result); // key/defaultValue jstrings still leaked return str; Each set/get leaves two extra local refs in the table. Loading many Hadoop/S3 properties will accumulate them until the thread detaches. 2. Constructor — local refs stored as members configurationClass = env->FindClass("org/apache/hadoop/conf/Configuration"); configurationObject = jniEnv->NewObject(configurationClass, initID); These are kept in Configuration.h as fields and reused by get/set. They must be global refs (NewGlobalRef then DeleteLocalRef on the originals). As written they occupy local-ref table slots for the object's lifetime. CarbonSchemaReader::readSchema also constructs a stack Configuration conf(jniEnv) and never releases those refs, so each call leaks two more. There is no ~Configuration() to DeleteGlobalRef even after a correct promotion. Note: after NewObject, the null check still tests configurationClass instead of configurationObject. Suggested fix After CallObjectMethodA, release the argument strings: jniEnv->DeleteLocalRef(args[0].l); jniEnv->DeleteLocalRef(args[1].l); In the constructor: jclass localClass = env->FindClass("org/apache/hadoop/conf/Configuration"); configurationClass = (jclass) env->NewGlobalRef(localClass); env->DeleteLocalRef(localClass); jobject localObj = env->NewObject(configurationClass, initID); configurationObject = env->NewGlobalRef(localObj); env->DeleteLocalRef(localObj); Add a destructor that DeleteGlobalRefs both. Prefer a small RAII wrapper so throws cannot skip cleanup. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
