JVM运行时数据区域
- 线程隔离的数据区:
-
程序计数器(Program Counter Register)
如果线程正在执行一个JAVA方法,这个记录器记录的是正在执行的虚拟机字节码指令地址;
如果 执行的是native方法,则记录空(undefined)。
此内存区域是Java虚拟机规范中没有规定任何OOM情况的区域。 -
虚拟机栈(VM Stack)
每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中如栈到出栈的过程;
可抛出OOM/StackOverflow。 -
本地方法栈(Native Method Stack)
为虚拟机使用到的Native方法服务;
可抛出OOM/StackOverflow。
- 线程共享的数据区
-
方法区(Method Area)
用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等;
可抛出OOM。 -
堆(Heap)
在虚拟机启动时创建,Java堆可以处于物理上不连续的空间中,只要逻辑上连续即可;
此区域存储了所有的对象实例和数组;
可抛出OOM。
普通Java对象的创建
-
类加载
如果在常量池中能定位到该类的符号引用,且该类已被加载,解析和初始化过,则跳过该步. - 分配内存
- 内存是规整: 指针碰撞(Bump the Pointer)
- 内存不规整: 空闲列表(Free List)
另外分配内存需要考虑操作的原子性, 使用CAS(Compare And Swap)或者TLAB(Thread Local Allocation Buffer)保证.
- 初始化分配的内存
- 设置对象
- 执行init()
package thread;
public class Parent {
{
System.out.println("parent block1");
}
static{
System.out.println("parent static block");
}
{
System.out.println("parent block2");
}
public static void test(){
System.out.println("parent test");
}
public Parent(){
System.out.println("parent init");
}
}
package thread;
public class Child extends Parent{
{
System.out.println("child block");
}
static{
System.out.println("child static block");
}
public static void main(String[] args) {
Child child = new Child();
System.out.println("done");
}
public Child(){
System.out.println("child init");
}
}
parent static block
child static block
parent block1
parent block2
parent init
child block
child init
done