您的位置:首页 > 编程语言 > Java开发

JVM系列(1)-Java内存区域

2017-12-26 21:53 267 查看


前段时间比较忙,公众号断更了一段时间,当下得空,准备写个JVM系列,JVM也就是Java Virtual Machine(Java虚拟机的缩写)。

考虑或者定位的问题的时候,经常会思考下数据的流向,那JVM是在哪个位置,哪个闸口呢?

问题1: JVM的位置

JVM在Java App和操作系统之间。Java语言不需要我们手工的释放或回收内存,这个工作由JVM来做。当然这也增加了学习成本,像C/C++在应用程序和操作系统之间没有JVM这一层,也就没有学习这一层的学习成本。“甘蔗没有两头甜”,在提供便利的同时,也增加了成本^_^,再透漏一点,Hotspot JVM实现就是用C++写的。



有刨根问底精神的程序员,是不是很想了解下JVM的内部结构,而且想把它搞的透亮,下面就引入第二个问题,JVM的内部结构。

问题2: JVM的内部结构

用内部结构这个词不一定那么准确,为了便于理解和讲述姑且先这样叫了。这里推荐个画图软件【亿图图示】,很好用^_^。

JVM有自己的内存空间,有的是所有线程共用的,有的是单个线程独有的。



各个区域有什么区别和联系,各自的作用又是啥?想不想知道^_^,那咱们就逐个分析讲解。

问题3:程序计数器

先问一个问题,Java是编译型语言还是解释型语言?你可能马上说是编译型语言,因为Java文件要先编译成.class文件。顺便插一句“什么是编译型语言,什么是解释型语言?”,编译型语言相当于整篇翻译,解释型语言相当于及时翻译,说一句,翻译一句。对Java而言,这有个参照物的区分,也就是说在JVM之上,Java是编译型语言,需要编译将.java文件生成.class文件;在JVM之下而言,它是解释型语言,因为在JVM是一句一句解释Java编译后的.class文件的。

说了这么多,那程序计数器和其有什么关联呢?

程序计数器可以理解为,当前线程,解释器要执行的字节码行号计数器,下一条需要执行哪条指令,程序计数器告诉你。

那程序计数器是所有线程共用的还是单个线程独有的呢?

我们可以推理一下,我们知道Java是一个支持多线程机制的语言,当一个线程运行一段时间后,要让出时间片和CPU,供另一个线程运行,之后,如果再次获得CPU和时间片,就继续执行。那继续从哪个指令执行呢?程序计数器里保存的有啊^_^。每个线程在切换的时候,执行到哪一步了,都不一样,也就是程序计数器记录的位置都不一样,每个线程独有各自的一个状态。因此,我们可以得出结论,程序计数器是各个线程独有的。

问题4:Java虚拟机栈

Java虚拟机栈记录的是Java方法执行的内存模型,是线程私有的。随着线程的销毁而销毁。是不是有点抽象?通俗的讲就是,虚拟机栈记录的是Java方法的执行的过程。记录的是个过程,Java方法执行的时候,要创建方法内的局部变量,内部逻辑要处理加工,对应的入栈和出栈都在这块内存中进行。如果堆栈深度过深,就会排除StackOverflowError异常,如果尝试者动态扩展,但是有没有申请到内存,就会排除OutOfMemoryError。

问题5:本地方法栈

我们知道了Java虚拟机栈,就很好理解本地方法栈了。Java虚拟机栈记录的是Java方法的执行过程,本地方法栈记录的就是本地方法的执行过程。

问题6:Java堆

首先堆是所有线程共享的一块区域;其次,这块区域的唯一目的就是存放对象实例;最后,这块区域是在JVM启动时创建,可以通过虚拟机参数-Xmx/-Xmn来控制大小。JVM的垃圾回收,基本都在这块区域;如果虚拟机采用的是分代的回收算法,那么这块区域还可进一步划分为新生代和老年代。

问题7:方法区

这块儿区域是所有线程共享的一块区域。主要用于存放类信息、常量、静态变量。

今天先到这儿,明个儿继续^_^

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jvm