今天我们继续谈谈 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 运行时组件的主要组成和主要功能.
来源: http://www.bubuko.com/infodetail-3100988.html