今天我们继续谈谈JVM架构。
今天主要讲讲JVM运行时,
先来一个图:
上篇文章,我们知道,JVM运行时,简单来说就是把class文件翻译成操作系统相关的机器码(或汇编语言),然后通过调用操作系统函数来完成程序运行的一个组件。
从详细方面来说,它又分为以下几个部分:
1.class文件加载系统(类加载器)
2.运行时数据区
3.执行引擎
首先,我们来看类加载器。类加载器主要的工作有:
简单来说,它主要的工作就是加载并初始化class文件。
再看看运行时数据 区,它主要是对内存的一个抽象,它主要分两块:堆(heap)和栈(stack)。当然还有程序计数器,这个以后再说。
什么是堆?
堆,简单来说,就是动态分配对象数据的区域,比如我们java程序里,用new关键词构造一个对象,那这个对象的数据就要在堆里面动态分配。
因为,这块要动态分配内存,就会涉及内存的回收,也就是GC,即垃圾回收。(下面会讲,先按下不表)
堆,打个比方,之前我们说,运行时组件,是class文件与操作系统之间的翻译器。我们可以想象一下,这个jvm运行时,就像一个翻译工作室。
这个翻译工作室里,有很多翻译工作者。这些翻译工作者,就是线程。
那这个堆,就是这个翻译者的草稿纸。每次翻译都要把一些有用的信息记下来,当然,最好用铅笔。
翻译完了,就把一些无用的信息用橡皮擦掉,这就是垃圾加收,即GC。
栈,打个比方,就像是这个翻译者的大脑,每次翻译,看到信息,在大脑里“缓存”一下。
当然,大脑里的数据,也就不用动态回收了,因为大脑可以短时记忆,下一次翻译,又重新“加载”新的信息。
简单来说,栈是随线程的,也就是线程私有的,根据程序上下文,来动态缓存数据的。就像每个翻译者,都有自己的大脑。都会用眼睛看一个英文单词,然后缓存在大脑。
而堆,是多线程共享的。就像每个翻译者都可以用同一张草稿纸来写字(当然,这个草稿纸要够大)。有同学说,大家都用一张草稿纸,会不会有冲突啊?
好问题!
这个工作室早想到这个问题!
解决方案就是:指定一个人专门拿橡皮擦,去动态清除无用的信息,并把有用的信息,抄写到固定的区域。
这个专门拿橡皮擦的人,就是GC线程,即垃圾回收器。
最后,说说执行引擎。
还是拿翻译工作室来比喻好了。
执行引擎,就是这个翻译工作室的业务员。他主要工作就是把翻译好的稿子,送给客户:操作系统。
让操作系统去执行这些稿子。这些稿子就是我们写的程序。从来完成java程序交给他们的工作。(这里java程序员,就是上帝的角色!)
并跟操作系统大BOSS交流沟通,讨价还价,打好关系。
当然,也是要从大BOSS里赚到钱和资源,才能养活这翻译工作室。
这些钱和资源,也就是操作系统里的:内存资源,CPU时间片资源,IO资源,网络资源。
以上,就是jvm运行时组件的主要组成和主要功能。