Java Native Interface(jni)和本地方法栈
这里简单提一下native
我们可以看到,在Object源码中,hashCode方法的前面有一个native
出现了native关键字的,说明java的作用范围达不到了,作用是调用非Java代码的接口,比如用C或者C++实现的
再回到我们的JVM体系结构
我们的本地方法接口就是JNI(java native interface)
而任何本地方法接口都会使用本地方法栈,本地方法栈和java栈十分相似,只不过一个是为了java虚拟机执行字节码服务,一个是为了执行native方法所服务
进入本地方法栈后,会调用本地方法接口(JNI)
至于为什么要用本地方法接口,原因就是拓展java的功能,融合不同的编程语言为Java所用
最初是想融合C和C++,因为当时C/C++用途广泛
所以在内存区域中,专门开辟了一块标记区域:本地方法栈,登记native方法
例如:java驱动打印机
主要是因为java无法对操作系统底层进行操作,但是可以通过jni(java native interface)(java本地接口)调用其他语言来访问底层
PC寄存器
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,,也即将要执行的指令代码),在执行引擎读取下一条指令
PC寄存器是一个非常小的内存空间,几乎可以忽略不计
方法区
方法区是被所有下成功向,所有字段和方法的字节码,以及一些特殊的方法,比如狗仔函数、接口代码也在此定义,简单说,所有定义的方法的信息都保存在该区域中,此区域属于共享区间
静态变量、常量、类信息(构造方法、接口定义),运行时的常量池存在方法区中,但是实例变量存在堆内存中,和方法区无关
static、final、类加载器、常量池
其中可以举个例子,创建一个学生类,其中有一个变量a和一个常量name
public class Student {
private int a;
private String name="elephant";
public static void main(String[] args) {
Student student=new Student();
}
}
在类加载中有
其中给name赋值为elephant,并不是代表name为常量,而是代表常量池中有一个String类型,值为“elephant”的字符串
当运行到
Student student=new Student();
会将student的引用压入java栈中同时将对应的数据放在堆中,并通过地址来查询堆中的数据
当没有给name赋值的时候,name不会创建一个新的数据elephant,而是会直接指向方法区中常量池的elephant的地址,如果赋予新值的话,就直接在堆中创建数据