jvm-运行时数据区域

今天我们说到jvm的运行时数据区域。
虚拟机要运行需要存储和修改数据,这一部分也是垃圾回收机制重点照顾的地方。

jvm-运行时数据区域_第1张图片
上图就是jvm运行时数据区域划分,其中 方法区和堆 也就是蓝色的部分是线程共享的,白色的区域时线程私有的。
1 堆 堆是整个java运行时最重要的一部分,我们创建的每一个对象(class对象除外)都要存在这里,在这里开辟空间。垃圾回收主要负责这一内存区域,也就是我们所说的gc区域。他主要是负责数据的存储的,,它分为Young Generation和Old Generation(也叫 Tenured Generation )两大部分。Young Generation分为Eden和Survivor,Survivor又分为From Space和 ToSpace。

2 方法区
方法区也有时候被人称之为永久代,这种说法也对也不对。因为他存储的编译的代码的具体信息,java文件的具体信息。还有每个.class文件 都对应一个class对象,虽然class是对象但是他存在方法区不存在堆中,且不可变的。
方法区是堆的逻辑区域,也叫做非堆,方法区的具体划分跟不同的虚拟机有关。
运行时常量池是方法区的一部分,存储的是字面量以及符号引用。我们写一段代码
jvm-运行时数据区域_第2张图片
用javap -verbose c.class命令进行输出看一下。

jvm-运行时数据区域_第3张图片

我们看到其中的 constant pool 部分就代表的常量池,存储的就是字面量和符号引用。(具体代表什么下期在讲)。
3 栈
如果说堆是保存运行时的数据,那么栈是保存程序如果执行的。栈的基本单位是栈桢,他的大小在编译的时候就已经确定了。同样可以看到上面的图,stack=2 ,locals=4,args_size=1 这些信息,代表栈的深读诗2 变量有4个 参数有一个。栈桢中有局部变量表,操作数栈,返回结果等信息。其中局部变量表中存储的是局部变量和参数。locals=4 也就是代表局部变量表索引为4 从1 开始。上面的图中的code 部分很明显的显示了栈的整个运行过程。首先这是栈的深入和局部变量表的空间,
吧int类型为100的数据压入栈顶
保存栈顶的数据到局部变量表中索引为1的位置
吧int 类型为98 的压入栈顶
保存栈顶的数据到局部变量表中索引为2的位置
取出局部变量表索引为1 的值 存入操作数栈
取出局部变量表中索引位2的值存入操作数栈
吧操作数栈中的数据想加并压入栈顶
吧栈顶的数据存入变量表索引为3的位置

jvm-运行时数据区域_第4张图片

4 本地方法栈
执行的是native 修饰的方法。通常来讲就是执行一些不是用java语言编写的代码。

5 程序计数器
保存当前线程所执行的字节码的行号指示器

一个关于string 的有意思的知识
String s1=new StringBuilder(“计算机”).append(“软件”).toString();
System.out.println(s1.intern() == s1);

String s2=new StringBuilder(“ja”).append(“va”).toString();
System.out.println(s2.intern() == s2);

上面的答案是有奇异的。
如果是jdk 1.6版本 false false intern()方法是把首次遇到的字符串复制到方法区中,是创建一个新的对象
如果是jdk 1.7版本以上 true false intern()方法是把首次遇到的对象的引用复制到方法区中并补创建对象
而“java”字符串本来就是存在于常量池中。

你可能感兴趣的:(jvm,jvm,虚拟机)