美文网首页
JNI&gcLocker整理

JNI&gcLocker整理

作者: andersonoy | 来源:发表于2017-07-15 14:32 被阅读0次

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

相关文章

  • JNI&gcLocker整理

    JNI & gclocker 整理 jni specificationhttp://docs.oracle.com...

  • 整理+整理+整理

    最近开启了整理狂魔的模式,各种资料整理,分类梳理,删删减减,颇有强迫症的赶脚,这是为了拖延正事才做的徒劳行为么? ...

  • 整理~整理~整理~

    整理过后,天晴了 乱了一段时间,把心放逐,让一切随风,但是离意却越差越远,面对诸多的不满意,通过发泄,自我调整,就...

  • 整理整理

    近两天状态不是很好,昨天原本计划好要写作业的,结果喝酒最终没有完成打卡,今天为此还是很焦虑,回家后为了消除情绪上的...

  • 整理整理

    在说点什么之前,先来讲讲一个叫康奈尔笔记法的小笔记法。 所谓的「康奈尔笔记法」,源自美国康奈尔笔记法故而得名,它是...

  • 整理整理

    今天突发奇想洗了洗地毯,结果清洗完地毯以后发现地板很脏,于是又拖了拖地,结果发现屋子又有点乱,然后就开始整理屋子,...

  • 整理整理

    最近已做好的事情: 完成了一篇论文,已投稿,发表应该问题已不大,前几天编辑说已过了二审,在等待三申,到现在没说让改...

  • 整理整理

    今天业余主要是把院长连线的与孩子人际关系的案例进行了一下整理和文字修改。 同时把前段时间整理的体验课的例子也整理完...

  • 整理整理

    家务真是越做越多。 不做的话就俩问题,脏和乱。做了就会冒出很多问题。 1、现在家里要面临被子没地方收的问题 解决方...

  • 整理整理github

    github:Reim nodejs写的简易留言板https://github.com/Reim/messageb...

网友评论

      本文标题:JNI&gcLocker整理

      本文链接:https://www.haomeiwen.com/subject/ehaahxtx.html