jvm体系结构 & 本地方法接口 & pc寄存器 & 方法区 &栈
线程是操作系统级别的,不是语言级别的。
因为Java语言中new Thread().start()中,其本质调用了一个native方法:start0();
native方法:调用的是和Java无关的底层的操作系统库或者C语言函数库。
本地方法接口(Native Interface)
由于栈中存放方法,所以栈分了两类:Java栈(又叫虚拟机栈)、本地方法栈(Native Method Stack)(里面存放native方法)
本地方法栈:
本地方法接口在本地方法栈中登记标记为native的方法,当执行引擎执行时,本地方法接口调用native方法库
程序计数器(Program Counter Register)(又叫PC寄存器)
用来存储指向下一条指令的地址,也即将要执行的指令代码,其本质就是一个指针,如果执行的是native方法,那这个指针是空的
属于灰色部分:即 线程私有(即每个线程对应一个PC寄存器)、内存占的特别少,几乎不存在垃圾回收
方法区:所有线程共享、有垃圾回收
方法区并不存放方法,而是存放类的模板(类的结构信息,以Class的形式存在,放在方法区中,由类加载器加载class得来)
方法区是一种规范,在不同虚拟机中实现是不一样的:
栈管运行
堆管存储
栈中主要存放方法(Java方法放进JVM中的虚拟机栈后,称为栈帧)(即一个方法对应一个栈帧)、基本变量、引用
栈中的方法又叫栈帧(Java方法放进JVM中的虚拟机栈后,称为栈帧)
所以栈中存放的是栈帧。
例如:在main方法里面调用m1()方法,则虚拟机栈如图所示:(m1方法执行完后,main方法才能执行完)
但其实,一般说栈帧里面存着两个东西:局部变量表+操作数栈
说完全点,是下面这些:
int i,j,k存在于局部变量表中,操作数栈中的结果赋值给局部变量表,++i、i++影响的是局部变量表中的数需不需要在放进操作数栈前先加1。
++i:修改局部变量表值直接加一,再放进操作数栈
i++:先把局部变量表中的值取出来放进操作数栈,再局部变量表直接加一
public static void main(String[] args) {
int i = 1;
i = i++;
int j = i++;
int k = i + ++i * i++;
System.out.println("i=" + i);
System.out.println("j=" + j);
System.out.println("k=" + k);
}
//运行结果:i=4,j=1,k=11
上一篇: JVM 本地方法接口、本地方法栈
下一篇: 回奶吃这些,,让你奶水充足好喂孩
推荐阅读
-
OOM实战:堆内存溢出 虚拟机栈和本地方法栈溢出 jvm栈容量太小 栈帧太大 栈太小,导致线程分配少,创建更多的线程将导致oom 方法区和运行时常量池溢出
-
JVM入门(位置、体系结构、类加载器、双亲委派机制、沙箱安全机制、Native、PC寄存器、方法区、堆(新生区{伊甸园区、幸存区}、养老区、永久区)、OOM、GC算法、JMM)
-
JVM 本地方法接口、本地方法栈
-
jvm体系结构 & 本地方法接口 & pc寄存器 & 方法区 &栈
-
JVM入门(位置、体系结构、类加载器、双亲委派机制、沙箱安全机制、Native、PC寄存器、方法区、堆(新生区{伊甸园区、幸存区}、养老区、永久区)、OOM、GC算法、JMM)
-
OOM实战:堆内存溢出 虚拟机栈和本地方法栈溢出 jvm栈容量太小 栈帧太大 栈太小,导致线程分配少,创建更多的线程将导致oom 方法区和运行时常量池溢出