栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在JNI中,如何根据IBM的性能建议来缓存类,方法ID和字段ID?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在JNI中,如何根据IBM的性能建议来缓存类,方法ID和字段ID?

没有可遵循的内置方法,但是这里有一些标准,简洁和可重复的实现,显示了我如何实践IBM的建议。

我假设您正在从Java调用DLL,并且在整个应用程序生命周期中多次引用它。

命名示例Native Java Class

org.stackoverflow.jni.NativeClazz
,它将实现2个内置JNI方法
JNI_onLoad()
JNI_onUnload()

void JNI_OnLoad(JavaVM * vm,void * reserved):
此方法将用于将类ID注册为全局变量,并将方法ID和字段ID分配给静态变量。当Java VM加载驱动程序时,将自动调用该方法。在驱动程序生命周期中仅调用一次。

void JNI_OnUnload(JavaVM * vm,void * reserved):
此方法将用于释放由注册的所有全局变量

JNI_onLoad()
。VM将
JNI_onUnload()
在应用程序关闭之前立即自动调用。

原理: 我的理解是必须将类ID注册为全局引用,以维护任何关联的方法ID
/字段ID的可行性。如果不这样做,并且从JVM卸载了类,则在重新加载类时,方法ID
/字段ID可能会不同。如果将类ID注册为全局引用,则不需要将关联的方法ID和字段ID注册为全局引用。将类ID注册为全局引用可以防止关联的Java类卸载,因此可以稳定方法ID
/字段ID的值。包括类ID在内的全局引用应在中删除

JNI_onUnload()

方法ID和字段ID不受本机代码管理;它们由虚拟机管理,并且在卸载相关的类之前一直有效。在虚拟机卸载定义类之前,无法显式删除字段ID和方法ID。卸载后,它们可以留给VM处理。

样例代码

以下C ++代码部分中的注释说明了全局注册变量。

这是

BeanObject
表示数据对象的Java类:

package org.stackoverflow.data;public class BeanObject {    String foo = "";    public String getFoo() {        return foo;    }}

这是一个基本的Java类

NativeClazz

package org.stackoverflow.jni;import org.stackoverflow.data.BeanObject;public class NativeClazz {    // Static area for forced initialization    static {        // Load Native Library (C++); calls JNI_onLoad()        System.loadLibrary("Native_Library_File_Name");    }        public static native void staticNativeMethod(BeanObject bean);        public native void instanceNativeMethod(BeanObject bean);}

这是使用

javah
on 生成的C ++头文件
NativeClazz

#include <jni.h>#ifndef _Included_org_stackoverflow_jni_NativeClazz#define _Included_org_stackoverflow_jni_NativeClazz#ifdef __cplusplusextern "C" {#endifJNIEXPORT void JNICALL Java_org_stackoverflow_jni_NativeClazz_staticNativeMethod  (JNIEnv *, jclass, jobject);JNIEXPORT void JNICALL Java_org_stackoverflow_jni_NativeClazz_instanceNativeMethod  (JNIEnv *, jobject, jobject);#ifdef __cplusplus}#endif#endif

这是实现头文件的C ++ .cpp文件:

#include "org_stackoverflow_jni_NativeClazz.h"using namespace std;static jclass JC_BeanObject;static jmethodID JMID_BeanObject_getFoo;static jint JNI_VERSION = JNI_VERSION_1_8;jint JNI_onLoad(JavaVM* vm, void* reserved) {    // Obtain the JNIEnv from the VM and confirm JNI_VERSION    JNIEnv* env;    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION) != JNI_OK) {        return JNI_ERR;    }    // Temporary local reference holder    jclass tempLocalClassRef;    // STEP 1/3 : Load the class id    tempLocalClassRef = env->FindClass("org/stackoverflow/data/BeanObject");    // STEP 2/3 : Assign the ClassId as a Global Reference    JC_BeanObject = (jclass) env->NewGlobalRef(tempLocalClassRef);    // STEP 3/3 : Delete the no longer needed local reference    env->DeleteLocalRef(tempLocalClassRef);    // Load the method id    JMID_BeanObject_getFoo = env->GetMethodID(JC_BeanObject, "getFoo", "(Ljava/lang/String;)V");    // ... repeat prior line for any other methods of BeanObject    // ... repeat STEPS 1-3 for any other classes; re-use tempLocalClassRef.    // Return the JNI Version as required by method    return JNI_VERSION;}void JNI_onUnload(JavaVM *vm, void *reserved) {    // Obtain the JNIEnv from the VM    // NOTE: some re-do the JNI Version check here, but I find that redundant    JNIEnv* env;    vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION);    // Destroy the global references    env->DeleteGlobalRef(JC_BeanObject);    // ... repeat for any other global references}JNIEXPORT void JNICALL Java_org_stackoverflow_jni_NativeClazz_staticNativeMethod    (JNIEnv * env, jclass clazz, jobject jBeanObject) {    // Retrieve jstring from the Java Object    jstring jFoo = (jstring)env->CallObjectMethod(jBeanObject, JMID_BeanObject_getFoo);    // Make accessible to C++    const char * cFoo = env->GetStringUTFChars(jFoo, NULL);    // Do something with cFoo...    // Release Resources    env->ReleaseStringUTFChars(jFoo, cFoo);    env->DeleteLocalRef(jFoo);}JNIEXPORT void JNICALL Java_org_stackoverflow_jni_NativeClazz_instanceNativeMethod    (JNIEnv * env, jobject selfReference, jobject jBeanObject) {    // Retrieve jstring from the Java Object    jstring jFoo = (jstring)env->CallObjectMethod(jBeanObject, JMID_BeanObject_getFoo);    // Make accessible to C++    const char * cFoo = env->GetStringUTFChars(jFoo, NULL);    // Do something with cFoo...    // Release Resources    env->ReleaseStringUTFChars(jFoo, cFoo);    env->DeleteLocalRef(jFoo);}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/452698.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号