深入探讨虚拟机运行时的java线程栈帧、Java/JVM沟通(5)
2023-04-29 来源:飞速影视
实际上,在日常开发中可以用javah生成C 函数,即JNI函数,它和Java的native方法“自动”对应,无须用到registerNative。这是因为虚拟机也会根据native方法名称和参数类型按照一定的规范查找JNI函数。根据用户编写的native方法找到对应的JNI函数是一个复杂的过程,虚拟机会经历一个很长的查找链。
1)解释器遇到native方法,调用InterpreterRuntime::prepare_native_call准备。2)prepare_native_call检查Method是否存在附加槽(是否已经有native入口),如果存在直接返回;如果不存在则用NativeLookup::lookup继续后面的查找过程。
3)NativeLookup::lookup调用Java代码ClassLoader.findNative。
4)findNative在synchronized块内寻找所有动态链接库,然后又调用一个native方法回到JVM层,这个native方法最终调用JVM_FindLibraryEntry。
5)JVM_FindLibraryEntry代理操作系统相关的动态链接APIos::dll_lookup。
6)os::dll_lookup平台相关,在Linux/OS X上调用dlsym(),在Windows上调用GetProcAddress。
查找native方法对应的JNI函数涉及多个状态层的转换,甚至还包含synchronized代码块,如图4-8所示。
如果使用registerNative提前注册,类初始化阶段会完成这些准备工作,否则上述开销将会推迟到运行时。
Method后面第二个槽signature_handler会在紧接着JNI入口设置后设置,它的作用和第2章提到的i2c/c2i适配器的作用一样:消除Java解释器栈和C栈调用约定的不同,将位于解释器栈中的参数适配到JNI函数使用的C栈。
本站仅为学习交流之用,所有视频和图片均来自互联网收集而来,版权归原创者所有,本网站只提供web页面服务,并不提供资源存储,也不参与录制、上传
若本站收录的节目无意侵犯了贵司版权,请发邮件(我们会在3个工作日内删除侵权内容,谢谢。)
www.fs94.org-飞速影视 粤ICP备74369512号