笔者不才,对JVM没有过深入的研究,所以也就只能分享一下JVM的基本结构,希望对没有了解过Java虚拟机的人并想了解一下JVM的同学有所帮助!
说起来Java虚拟机是有蛮多种的,比如HotSpot、OpenJDK、JRockit等。不过,不管是那类的虚拟机,其基本结构都是差不多的,只是存在些许差别。
Java虚拟机的大概结构
其中,堆、Java栈、本地方法栈、方法区、程序计数器组成的区域统称为运行时数据区域!
下面来讲讲运行时数据区域各个部分的作用
堆:主要存储的是Java对象的实例以及数组,是GC管理的主要区域。
Java栈:每当方法执行时,jvm都会创建一个栈帧,以便来存储局部变量表、方法出口、操作数栈等,其生命周期跟线程一致,方法的开始以及结束就是入栈与出栈。局部变量表就是存储已知的八大基本类型(int、float等)、对象引用等。
本地方法栈:其实与Java栈差不多的,知识负责的区域不一样,Java栈负责的是Java的方法,本地栈负责的是本地的方法。
方法区:主要存储的是类的信息、常量、静态变量、加载过后的代码(class文件)等。在其中有一个区域为常量区,分为编译时以及运行时的常量区,主要存储编译时产生的字面量以及符号引用,在运行时可以调用String类的intern方法把将新常量放进常量池中。
字面量与符号引用:字面量:比如int i=“12”;String s=“ss”,其中的12和ss就是字面量;符号引用:当类引用另一个类的时候,比如man类需要引用people时,people还没加载时,man类并不知道people类在那个位置,只能用一个符号来表示people类,这个符号就是符号引用。
程序计数器:其实按照笔者的理解就是存放下一条指令的地方,字节码的解释工作就是由它完成的,在运行时数据区域就只有它不会出现OutOfMemory Error(内存溢出)。
一个new对象的大致过程:虚拟机接到new指令时,首先查找是否有这个类的符号引用,看是否被加载过,没被加载的先由类加载器加载。加载完成之后就要为new出来的对象在堆中分配内存,分配完内存之后需要对内存进行初始化为零,然后再对对象进行设置,比如对象头啊,哈希码之类的,当然最后还是要执行init方法的,为对象字段等初始化值(程序员决定的)。
当然为了能够使用新创建的对象,必须要在Java栈中创建一个对象的引用,这个对象的引用就是堆中实例的地址。
好了,笔者这次分享就到此为止了,希望对你有所帮助,如果那位大神发现哪里笔者讲错了,请指教,万分感谢!