来谈谈JVM -运行时数据区

2016-12-08  本文已影响0人  Michael_Zhou

面试的时候经常问应聘者,你知道java虚拟机的内存结构吗?堆栈之类的内存结构。在应聘者一脸茫然的时候我就会补充一句,也就是问你:堆里面放什么,栈里面放什么?

其实严格的说:这个问题本身就不准确,严谨的问法是:“你了解java虚拟机运行时数据结构吗?”

好的, 下面我们就来谈谈这个话题。

java虚拟机运行时数据结构,按照生命周期大体可以分两类,一类是线程共享的,包括推和方法区,随着虚拟机进程的启动而创建,随着虚拟机进程的停止方销毁。另一类是线程独享的,包括java栈,本地方法栈和程序计数器。


先来说说线程共享的堆和方法区。

堆:

简单来说,new出来的对象都放在堆里面。稍微官方一点的说法:提供所有类实例和数组对象分配内存的区域,这块区域也是GC主要关注的地方。堆又可以细分为:新生代,老年代,永久代,这个咱们回头有空单独拿一篇文件来介绍。(根据虚拟机规范的规定,Java堆可以是固定的大小也可以是按照需求动态扩展的,而且不需要保证是连续的。)总之,这块区域是GC主要关注的地方。

方法区:

用于存储已经被虚拟机加载的类信息、常量、静态变量。方法区还包含运行时常量池,用于存放编译时生成的各种字面量和符号引用,但是不要求常量一定是在编译时期产生的,运行期间也可以将新的常量放入池中,比如String的intern()方法便是利用了这一特性。总而言之:方法区存放内容:类的结构信息,如类的字段、方法、接口、构造函数,还有运行时常量池等。

然后就是线程独享的:

程序计数器:

存放内容:如果线程执行的是一个Java方法,那么寄存器里面记录的就是正在执行的虚拟机字节码指令的地址,如果线程执行的是一个native方法,那么寄存器记录的值为undefined。

虚拟机栈:

虚拟机栈也是线程私有的内存区域。每个方法在执行的时候都会创建一个栈帧用于存储局部变量表、操作数栈、方法出口等信息,每一个方法从调用到执行完成就是一个栈帧入栈和出栈的过程。局部变量表存放了编译时期可知的各种基本数据类型、对象引用和指向了一条字节码指令的地址。存放内容:局部变量表、操作数栈、方法出口等信息。

本地方法栈:

和虚拟机栈类似,存储Native方法的相关信息。存放内容:局部变量表、操作数栈、方法出口等信息。

上一篇 下一篇

猜你喜欢

热点阅读