JVM,全称Java Virtual Machine,即Java虚拟机。我们以Java作为编程语言所编写的应用程序都是运行在这上面的。JVM对程序的执行主要分为两个步骤,第一步是编译,即将.java的源文件编译成为.class的字节码文件,第二步是解释,JVM对字节码文件进行解释执行。
更进一步的研究,我们会发现,JVM整个大系统又分为两个子系统,第一个是ClassLoader,即类加载器,功能则是将我们编写的类加载到JVM当中来。我们可以继承ClassLoader这个类来实现我们自己的类加载器,至于具体如何让JVM使用我们的自定义ClassLoader还有待研究;第二个是Execution Engine,即执行引擎,负责对编译后的字节码文件进行解释执行。而Execution Engine又分为两部份,第一部份是Runtime data area,即运行时数据区域,这就相当于JVM中的内存,而第二部份则是Native interface,即本地化接口,主要用于执行其他非java编程语言编写的程序。这里面的重点就是Runtime data area。RDA又分为五个部分,分别是Method area 方法区域,Java stack Java栈,Heap 堆,Program counter 程序计数器,Native method stack 本地方法栈。 堆又分为三个部份,第一部份是Young年轻代,第二部份是Tenured年老代,第三部份是Perm持久代。年轻代又分为Eden,Survivor I,Survivor II三个部份。现在来看看JVM的构图吧。
现在再来详细了解一下Runtime data area中的各个组成部份。
1.Java stack
Java栈是一个内存块,一个数据集,遵循先进后出的原则。如当A方法被调用时,A被压入栈,而A方法中又调用了B方法,B方法被压入栈,执行完毕时,B方法先出栈,然后才是A方法出栈。栈中存放的数据主要是本地变量,即输入输出参数,形式参数。栈中的数据被应用程序的每一个线程所拥有,当线程结束,那么栈中的数据也就消失了。所以不存在垃圾回收的问题。
2.Heap
对象的实例就存放在堆中。因为堆中的数据是被应用程序的所有线程所共享的,所以可能会引发同步问题,这是需要我们考虑的,而且Java中的GC就是针对堆中的数据进行垃圾回收处理的。来看看堆的结构吧。