目录
使用PC寄存器存储字节码指令地址有什么用呢?为什么使用PC寄存器记录当前线程的执行地址呢?
在Java虚拟机的运行时数据区种,红色部分的是随着虚拟机的创建而创建,随着虚拟机的销毁而销毁,而灰色部分是每个线程一份
PC寄存器用来存储指向下一条指令的地址。也即将执行的指令代码,有执行引擎读取下一条指令。与线程生命周期一致。
因为CPU需要不停的切换各个线程,这时候切换回来以后,就得直到接着从哪开始继续执行。JVM字节码解释器的值来明确下一条应该执行什么样的字节码指令。
主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。
每逢线程创建的时候都会创建一个虚拟机栈,虚拟机栈里面保存的是一个个的栈帧,一个栈帧就对应一个Java方法的调用。每个方法被调用直至执行完毕,就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。
保存的8中基本数据类型、对象的引用地址。
这也就是为什么在静态方法中不能应用this变量,因为在静态方法的局部变量表的局部变量槽中没有放该数据;而构造方法和实例方法中的局部变量槽的Index为0的位置是放了this。
变量的分类:
按照数据类型分:①基本数据类型 ②引用数据类型
按照类中声明的位置分:①成员变量:都经历过默认初始化阶段
类变量(静态变量):linking的prepare阶段:给类变量默认赋值->initial阶段进行显式赋值
实例变量:随着对象的创建会在堆空间中分配实例变量空间,并进行默认赋值
②局部变量:在使用前必须进行显示赋值,否则编译不通过
StackOverFlowError:通过-xss设置栈的大小,可以设置为固定大小和动态大小,固定大小的情况下不断加栈帧会导致栈溢出。
不能保证。只能是让StackOverFlowError出现的更晚。
不是,因为
不会。只有进栈出栈。
具体问题具体分析:
例如:使用线程不安全的类StringBuilder(内部没有加同步锁)来举例子,不然如果使用StringBuffer,本身就是线程安全的就没意义了
在method1里面的s1是线程安全的。因为一个线程操作这个数据。
例子二:这里的StringBuilder是以参数的形式传入的
sBuilder操作的过程是线程不安全的,因为该对象的引用地址是以参数形式传进来,并不是单独保存在该线程里面,所以是线程不安全的
Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用
一个Java程序启动的时候就会创建一个Java虚拟机实例,一个Java虚拟机实例里面只存在一个堆空间。
线程共享的堆可以划分出多个线程私有的分配缓冲区TLAB,以提升对象分配时的效率。
(几乎)所有的对象实例以及数组都应当在运行时分配在堆上。
是各个线程共享的内存区域,用于存储被虚拟机加载的
类型信息常量、静态变量即时编译器编译后的代码缓存等数据。
用于存放编译时期生成的各种字面量与符号引用(例如字面量String、System),这部分内容将在类加载后存放到方法区的运行时常量池中。
运行时常量池中包含多种不同的变量,包括编译期就已经明确的数值字面量,也包括到运行期解析后才能够获得的方法或者字段引用,此时不再是常量池中的符号地址了,这里换为真实地址。