zhangstar333 commented on code in PR #56763:
URL: https://github.com/apache/doris/pull/56763#discussion_r2497151773


##########
be/src/util/jni-util.h:
##########
@@ -72,138 +59,1114 @@ class JniUtil {
                 return status;
             }
         }
-        if (*env == nullptr) {
+        if (*env == nullptr) [[unlikely]] {
             return Status::JniError("Failed to get JNIEnv: it is nullptr.");
         }
         return Status::OK();
     }
 
-    //jclass is generally a local reference.
-    //Method ID and field ID values are forever.
-    //If you want to use the jclass across multiple threads or multiple calls 
into the JNI code you need
-    // to create a global reference to it with GetGlobalClassRef().
-    static Status GetGlobalClassRef(JNIEnv* env, const char* class_str,
-                                    jclass* class_ref) WARN_UNUSED_RESULT;
-
-    static Status LocalToGlobalRef(JNIEnv* env, jobject local_ref,
-                                   jobject* global_ref) WARN_UNUSED_RESULT;
+    static Status Init() { return init_throw_exception(); }
 
     static Status GetJniExceptionMsg(JNIEnv* env, bool log_stack = true,
                                      const std::string& prefix = "") 
WARN_UNUSED_RESULT;
 
-    static jclass jni_util_class() { return jni_util_cl_; }
-    static jmethodID throwable_to_stack_trace_id() { return 
throwable_to_stack_trace_id_; }
+private:
+    static Status GetJNIEnvSlowPath(JNIEnv** env);
+    static Status init_throw_exception() {
+        JNIEnv* env = nullptr;
+        RETURN_IF_ERROR(Jni::Env::Get(&env));
+
+        if (env == nullptr) {
+            return Status::JniError("Failed to get/create JVM");
+        }
+        // Find JniUtil class and create a global ref.
+        jclass local_jni_util_cl = 
env->FindClass("org/apache/doris/common/jni/utils/JniUtil");
+        if (local_jni_util_cl == nullptr) {
+            if (env->ExceptionOccurred()) {
+                env->ExceptionDescribe();
+            }
+            return Status::JniError("Failed to find JniUtil class.");
+        }
+        jni_util_cl_ = 
reinterpret_cast<jclass>(env->NewGlobalRef(local_jni_util_cl));
+        if (jni_util_cl_ == nullptr) {
+            if (env->ExceptionOccurred()) {
+                env->ExceptionDescribe();
+            }
+            return Status::JniError("Failed to create global reference to 
JniUtil class.");
+        }
+        env->DeleteLocalRef(local_jni_util_cl);
+        if (env->ExceptionOccurred()) {
+            return Status::JniError("Failed to delete local reference to 
JniUtil class.");
+        }
+
+        // Throwable toString()
+        throwable_to_string_id_ = env->GetStaticMethodID(
+                jni_util_cl_, "throwableToString", 
"(Ljava/lang/Throwable;)Ljava/lang/String;");
+        if (throwable_to_string_id_ == nullptr) {
+            if (env->ExceptionOccurred()) {
+                env->ExceptionDescribe();
+            }
+            return Status::JniError("Failed to find JniUtil.throwableToString 
method.");
+        }
 
-    static const int64_t INITIAL_RESERVED_BUFFER_SIZE = 1024;
-    // TODO: we need a heuristic strategy to increase buffer size for 
variable-size output.
-    static inline int64_t IncreaseReservedBufferSize(int n) {
-        return INITIAL_RESERVED_BUFFER_SIZE << n;
+        // throwableToStackTrace()
+        throwable_to_stack_trace_id_ = env->GetStaticMethodID(
+                jni_util_cl_, "throwableToStackTrace", 
"(Ljava/lang/Throwable;)Ljava/lang/String;");
+        if (throwable_to_stack_trace_id_ == nullptr) {
+            if (env->ExceptionOccurred()) {
+                env->ExceptionDescribe();
+            }
+            return Status::JniError("Failed to find 
JniUtil.throwableToFullStackTrace method.");
+        }
+        return Status::OK();
     }
-    static Status get_jni_scanner_class(JNIEnv* env, const char* classname, 
jclass* loaded_class);
-    static Status convert_to_java_map(JNIEnv* env, const std::map<std::string, 
std::string>& map,
-                                      jobject* hashmap_object);
-    static Status convert_to_cpp_map(JNIEnv* env, jobject map,
-                                     std::map<std::string, std::string>* 
resultMap);
-    static size_t get_max_jni_heap_memory_size();
-    static Status clean_udf_class_load_cache(const std::string& 
function_signature);
 
 private:
-    static void parse_max_heap_memory_size_from_jvm(JNIEnv* env);
-    static Status GetJNIEnvSlowPath(JNIEnv** env);
-    static Status init_jni_scanner_loader(JNIEnv* env);
+    // Thread-local cache of the JNIEnv for this thread.
+    static __thread JNIEnv* tls_env_;
 
-    static bool jvm_inited_;
-    static jclass internal_exc_cl_;
-    static jclass jni_native_method_exc_cl_;
+    //for exception
     static jclass jni_util_cl_;
     static jmethodID throwable_to_string_id_;
     static jmethodID throwable_to_stack_trace_id_;
-    static jmethodID get_jvm_metrics_id_;
-    static jmethodID get_jvm_threads_id_;
-    static jmethodID get_jmx_json_;
-    // JNI scanner loader
-    static jobject jni_scanner_loader_obj_;
-    static jmethodID jni_scanner_loader_method_;
-    // Thread-local cache of the JNIEnv for this thread.
-    static __thread JNIEnv* tls_env_;
-    static jlong max_jvm_heap_memory_size_;
-    static jmethodID _clean_udf_cache_method_id;
 };
 
-/// Helper class for lifetime management of chars from JNI, releasing JNI 
chars when
-/// destructed
-class JniUtfCharGuard {
+enum RefType { Local, Global };
+
+enum BufferType { Chars, ByteArray };
+
+template <RefType Ref>
+struct RefHelper {};
+
+template <>
+struct RefHelper<Local> {
+    static jobject create(JNIEnv* env, jobject obj) { return 
env->NewLocalRef(obj); }
+
+    static void destroy(JNIEnv* env, jobject obj) { env->DeleteLocalRef(obj); }

Review Comment:
   could we maybe set this local reference to be automatically deleted after 
use?
   Recently,  noticed that local references can also cause memory leaks.



-- 
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]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to