JNI&gcLocker整理

JNI & gclocker 整理

  • jni specification

  • JNI HelloWorld( windows下是.dll文件,linux下是.so文件 )

    • Java代码
      public class JNIDemo { public native void sayHello(); public static void main(String[] args){ //调用动态链接库 System.loadLibrary("JNIDemo"); JNIDemo jniDemo = new JNIDemo(); jniDemo.sayHello(); } }
    • 生成头文件
      • javah com.jni.demo.JNIDemo
    • 使用VC6.0生成.dll文件
      • Win32 dynamic-link library
      • .cpp文件输入
        JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_sayHello (JNIEnv * env, jobject obj) { cout<<"Hello World"<<endl; }
      • 编译成功,生成JNIDemo.dll文件在C++工程中的Debug目录中
    • 将JNIDemo.dll文件添加到path环境变量中
  • 参数解释

    • (JNIEnv * env, jobject obj)
    • JNIEnv类型实际上代表了Java环境,通过这个JNIEnv* 指针,就可以对Java端的代码进行操作
    • JNIEnv类中有很多函数可以用
      • NewObject:创建Java类中的对象
      • New<Type>Array:创建类型为Type的数组对象
      • Set<Type>Field:设置类型为Type的字段的值
      • Call<Type>Method:调用返回类型为Type的方法
      • 具体的可以查看jni.h文件中的函数名称
    • jobject
      • 如果native方法不是static的话,这个obj就代表这个native方法的类实例
      • 如果native方法是static的话,这个obj就代表这个native方法的类的class对象实例(static方法不需要类实例的,所以就代表这个类的class对象)
    • jclass str = env->FindClass("java/lang/String");获取Java中的String对象的class对象
    • 在C/C++本地代码中访问Java端的代码,一个常见的应用就是获取类的属性和调用类的方法
    • { //获取obj中对象的class对象 jclass clazz = env->GetObjectClass(obj); //获取Java中的number字段的id(最后一个参数是number的签名) jfieldID id_number = env->GetFieldID(clazz,"number","I"); //获取number的值 jint number = env->GetIntField(obj,id_number); //输出到控制台 cout<<number<<endl; //修改number的值为100,这里要注意的是jint对应C++是long类型,所以后面要加一个L env->SetIntField(obj,id_number,100L); }
  • jni critical functions

    • GetStringCritical, ReleaseStringCritical
      • const jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy);
      • void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);
      • The semantics of these two functions are similar to the existing Get/ReleaseStringChars functions
      • If possible, the VM returns a pointer to string elements; otherwise, a copy is made. However, there are significant restrictions on how these functions can be used. In a code segment enclosed by Get/ReleaseStringCritical calls, the native code must not issue arbitrary JNI calls, or cause the current thread to block
      • The restrictions on Get/ReleaseStringCritical are similar to those on Get/ReleasePrimitiveArrayCritical.
      • After calling GetPrimitiveArrayCritical, the native code should not run for an extended period of time before it calls ReleasePrimitiveArrayCritical. We must treat the code inside this pair of functions as running in a "critical region." Inside a critical region, native code must not call other JNI functions, or any system call that may cause the current thread to block and wait for another Java thread. (For example, the current thread must not call read on a stream being written by another Java thread.)
      • These restrictions make it more likely that the native code will obtain an uncopied version of the array, even if the VM does not support pinning.
    • For example, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical.
  • gc locker

    • GC_Locker用于解决JNI临界区内数据一致性问题
    • 使用JNI临界区的方式操作数组或者字符串时,为了防止GC过程中jarray或者jstring发生位移,而导致数组指针失效,
      需要保持它们在JVM Heap中的地址在JNI Critical过程中保持不变。于是JVM实现了GC_locker,用于JNI Critical内阻止其他GC的发生。
      当GCLocker被激活且需要发生GC的时候(这里是否需要GC是各种GC发生时,调用GCLocker::check_active_before_gc()函数check并设置_needs_gc = true的),就会阻塞其他线程进入JNI临界区;
      并且在最后一个位于JNI临界区的线程退出临界区时,发起一次CGCause为_gc_locker的GC。这里解释了GCLocker Initiated GC发生的原委
    • VM为什么选择pin住Heap(为了提高性能,还可以采用pin住JNI临界区的数据所属Region或直接pin住临界区数据的方式)阻止在Critical Region时发生GC,而不选择类似NIO中DirectByteBuffer的方式将Java Heap中的data先行拷贝到C Heap中,主要原因是避免因为数据拷贝导致的开销,从而提高JNI的性能
    • VM内部触发GC时,需要先行判断GC_Locker的状态是否active, 如果被激活则直接返回,不做GC了
    • // 6. Check if the GC_locker is active. if (GC_locker::check_active_before_gc()) { return; // GC is disabled (e.g. JNI GetXXXCritical operation) }
    • gclocker表示有native方法在执行,这个时候native方法会需要访问jvm中的对象,通过地址访问,如果这个时候发生gc,那么对象有可能被移动了,那native方法访问就会有问题。所以需要lock住gc
    • 各种gc causes http://netflix.github.io/spectator/en/latest/ext/jvm-gc-causes/
      • GCLocker_Initiated_GC
        • The GC locker prevents GC from occurring when JNI code is in a critical region. If GC is needed while a thread is in a critical region, then it will allow them to complete, i.e. call the corresponding release function. Other threads will not be permitted to enter a critical region. Once all threads are out of critical regions a GC event will be triggered.
  • JVM Anatomy Park #9: JNI Critical and GC Locker

    • "JVM Anatomy Park" is the mini-post series, where every post is slated to take 5-10 minutes to read (and no more than 2 hours for me to write).
  • References

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容