03运行时数据区
目录:
1、
运行时数据区内部结构与
JVM中的线程说明
2、
PC寄存器概述
3、
虚拟机栈
4、栈的相关面试题
5、堆
6、方法区
1、 运行时数据区内部结构与JVM中的线程说明
![](https://i-blog.csdnimg.cn/blog_migrate/b6b71cfff030a527db33eee6d8a3a992.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0063e0f921370e77c0abcc1a8b8d55fa.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4e841172cbf14ad93fe658752ccedf6c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6384b07744c3b657fbf7e540e6f9e4cb.png)
2、 PC寄存器概述
![](https://i-blog.csdnimg.cn/blog_migrate/cb144b418e640dd69e15842c1d6d3651.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e933c663bcbeffe3bf02032d88825398.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b6b71cfff030a527db33eee6d8a3a992.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5101a846de6b21c7290bedff39961df0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/572aef9f0a241c1aa5ba17c1ed00e076.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5101a846de6b21c7290bedff39961df0.png)
3、 虚拟机栈
![](https://i-blog.csdnimg.cn/blog_migrate/33e9a3fd5bf3fd6bb4d3422c30f07be5.png)
![](https://i-blog.csdnimg.cn/blog_migrate/198f580f0c7a373e036a083252aac8e5.png)
![](https://i-blog.csdnimg.cn/blog_migrate/505f2ca2106225b47c300de273d66615.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c6a01e346a4ef6f149800547da4f9d08.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1d3bf6623ff24441d42d9de205242abd.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9f39826ea8c8793eb4a9a3f80769e89f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b292cc52f9dd5936e6732d5895e8a19d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/97fd424971ad1037fd70d91c3e199ba4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5522ab06151ee5a0ce4aa0eeea19cc2c.png)
1、局部变量表
![](https://i-blog.csdnimg.cn/blog_migrate/52b4c81d9a3b110c7efd1193356fe888.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3f5a79497f192799ad9f98a4138ce88a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cb144b418e640dd69e15842c1d6d3651.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3f5a79497f192799ad9f98a4138ce88a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5655a1ad2d4fc9948fc2a8c8d514ca87.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d09ab6db71832e649a4ae9a95c2148c7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c01401ab23634416f6574a8d8df0839b.png)
2、操作数栈
![](https://i-blog.csdnimg.cn/blog_migrate/42059702d29b1aa97b9d30607aa0a601.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cb261cf0196e2ddfc0bc1383fbccf5d9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/89d1010bf2972ceb41342adc677b7626.png)
![](https://i-blog.csdnimg.cn/blog_migrate/67e977a90f5005f04967e2459e58c38e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/97fd424971ad1037fd70d91c3e199ba4.png)
3、动态链接
![](https://i-blog.csdnimg.cn/blog_migrate/7de44da5b35ce571c5e01ce1b4a05887.png)
![](https://i-blog.csdnimg.cn/blog_migrate/19c870d81701557bd6fde1e89a63abe0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/42059702d29b1aa97b9d30607aa0a601.png)
![](https://i-blog.csdnimg.cn/blog_migrate/19c870d81701557bd6fde1e89a63abe0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/dc99b300b9efdfd8f5c67738b0b711dc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5bec3630146176bbcfd3fb92b0ce0203.png)
4、方法返回地址
![](https://i-blog.csdnimg.cn/blog_migrate/0063e0f921370e77c0abcc1a8b8d55fa.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d09ab6db71832e649a4ae9a95c2148c7.png)
5、栈针的附加信息
![](https://i-blog.csdnimg.cn/blog_migrate/9f39826ea8c8793eb4a9a3f80769e89f.png)
4、栈的相关面试题
![](https://i-blog.csdnimg.cn/blog_migrate/97fd424971ad1037fd70d91c3e199ba4.png)
5、堆
1. 堆的概述
①.存放的东西:对象本身、全局变量 [ 成员变量 ]
②. 特点:
a.它是线程共享的,堆中对象都需要考虑线程安全的问题
b.有垃圾回收机制
2.
堆内存内部结构
①. 所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx 和Xms来控制
②. 堆被划分为新生代和老年代,新生代又被进一步划分为Eden(伊甸园)和Survivor(幸存者)区,老年代,在后面不是堆区是永恒代(方法区)
![](https://i-blog.csdnimg.cn/blog_migrate/85d42f67252bde28fb1710df41151b10.png)
③. 伊甸园满了,就会触发gc(minor gc),而gc就会把标识为垃圾的对象干掉,不是垃圾的对象就要转移到幸存区,把伊甸园让出来给新的对象用
![](https://i-blog.csdnimg.cn/blog_migrate/5a26f31d71095cdf7305e644bd8a0d6d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ab4cc4d5a3de918b2c48f3b6a89bf13e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d90f564ced60462116a3e75912ee69ca.png)
3.
养老区
养老区用于保存从新生区筛选出来的Java对象,一般池对象都在这个区域活跃
①. Eden 和survivor的比例是8:1,年轻代中的对象基本都是朝生夕死(80%以上),老年代比年轻代内存大。如果老年代内存满了,就会触发majorGC 或者 full GC
②. full GC 就会出现所谓的STW(stop the world)现象,即所有的进程都挂起等待清理垃圾
③. major GC 是回收老年代的垃圾;Full GC是回收老年代和年轻代的垃圾
如果出现 java.lang.OutOfMemoryError : Java heap space 异常,说明Java虚拟机的堆内
存不够:由如下两种原因
1.Java 虚拟机的堆内存设置不够,可以通过参数 -Xms 、Xmx 来调优
2.代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)
5.
永久代
永久储存是一个常驻内存区域,用于存放JDK自身所携带的Class,Interface 的元数据,也就是说它存储的是运行坏境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭JVM才会释放此区域所占用的内存
//java.lang.OutOfMemoryError : PermGen space如果出现
java.lang.OutOfMemoryError : PermGen space, 说明是Java虚拟机堆永久代Perm内存设置不够。
一般出现这样情况,都是程序启动需要加载大量的第三方jar包。例如:在 一个Tomcat 下部署了太多的应用。需要大量动态反射生成的类不断被加载,最终导致Perm区被占满。
![](https://i-blog.csdnimg.cn/blog_migrate/623eb1f83227afc418041e59d78f19a2.png)
①. Jdk 1.6 及之前:有永久代,常量池1.6在方法区
②. Jdk 1.7 :有永久代,但已经逐步 " 去永久代 ",常量池1.7 在堆中
③. jdk 1.8 及之后: 无永久代,常量池1.8在元空间
JdK1.7之前
![](https://i-blog.csdnimg.cn/blog_migrate/cb261cf0196e2ddfc0bc1383fbccf5d9.png)
Jdk1.7开始
![](https://i-blog.csdnimg.cn/blog_migrate/5c030c6b2891ab9dad4a48c53c618cba.png)
一.常量池共有三类:
1.运行时常量池
2.Class文件常量池
3.字符串常量池
二. 详解
常量池(Constant Pool)
1.1 常量池(Class文件常量池):.java经过编译后生成的.class文件,是Class文件的资源仓库。
1.2 常量池中主要存放俩大常量:字面量(文本字符串,final常量)和符号引用(类和接口的全局定名,字段的名称和描述,方法的名称和描述),如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/73d63ef0165250c4a8a7b5e4fae9a50a.png)
2. 运行时常量池(Constant Pool)
运行时常量池是方法区的一部分。在Class常量池中,用于存放编译期间生成的字面量和符号量,在类加载完之后,存入运行时常量池中。而运行时常量池期间也有可能加入新的常量(如:String.intern方法)
3. String常量池,
String常量池,JVM为了减少字符串对象的重复创建,在堆区开一段内存存放字符串。
6.
jdk1.7 和 jdk1.8 堆中结构区别
①.jdk1.7 堆中的结构
![](https://i-blog.csdnimg.cn/blog_migrate/64407a276dc4e3f0d27f1523cc71a554.png)
②. jdk 1.8 堆中的结构
![](https://i-blog.csdnimg.cn/blog_migrate/67a53a916aaae578e086b4f057959e89.png)
//Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
//java虚拟机中堆内存是2022m也就是2g多
System.out.println(Runtime.getRuntime().maxMemory()/1024/1024);
//这里没有超过God 111 可以输出
/*byte[]byteArray=new byte[1*1024*1024*2000];
System.out.println("God 111");*/
//这里超过了2g多,会抛出Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
byte[]byteArray=new byte[1*1024*1024*2020];
System.out.println("God 111");
7.
jps | jmap | jconsole的使用
public class test {
public static void main(String[] args) {
System.out.println("1...."); try { TimeUnit.SECONDS.sleep(30); } catch (InterruptedException e) {e.printStackTrace();}
byte[]bytes=new byte[1024*1024*10];
System.out.println("2....");
try { TimeUnit.SECONDS.sleep(30); } catch (InterruptedException e) {e.printStackTrace();}
bytes=null;
System.gc();
System.out.println("3....");
try { TimeUnit.SECONDS.sleep(20); } catch (InterruptedException e) {e.printStackTrace();}
}
}
演示jps和jmap如下:
1.在byte还没创建前
![](https://i-blog.csdnimg.cn/blog_migrate/9da2fef19c540c3d72ce918830f463ff.png)
2.创建了一个10M的byte的数组
![](https://i-blog.csdnimg.cn/blog_migrate/6fef2a39d4c90cf5202bff2840b4e9d2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6fef2a39d4c90cf5202bff2840b4e9d2.png)
jconsole演示:
![](https://i-blog.csdnimg.cn/blog_migrate/9da2fef19c540c3d72ce918830f463ff.png)
6、方法区
1. 方法区的概述
存储的东西:
静态变量+常量+类信息+运行时常量池存在方法区中 [ 掌握 ]
①. 所有Java虚拟机线程共享的区域,存储了类结构相关的信息 [ 成员变量、方法、构造器 ]等
②. 方法区的创建是在Java 虚拟机启动时被创建
③. 方法区时逻辑上时堆的一个组成部分,但是在不同虚拟机里头实现是不一样的,最典型的就是永久代(PermGen space)和元空间(Metaspace)
注意:方法区时一种规范,而永久代和元空间是它的一种实现方式
④. 方法区存在OOM现象
2. 常量池和运行时常量池
①. 常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
②. 运行时常量池,常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
③. 进入class的目录,javap -v 类.class
二进制字节码(类基本信息+常量池+类的方法定义[包含了虚拟机指令])
如下代码重点掌握
public class StringTableDemo1 {
/*
1.常量池中的信息,都会被加载到运行时常量池,这是a b ab 都是常量池中
的符号,还没有变成Java字符串对象
2.ldc #2 会把a符号变成字符串对象,会为StringTable开辟一个空间,
在StringTable中查看a是否存在,如果不存在,就添加进去,如果存在,
就用StringTable中有的;b ab都是这个过程
* */
public static void main(String[] args) {
String s1="a";
String s2="b";
String s3="ab";
//new StringBuilder().append("a").append("b").toString();
//new String("ab");
String s4=s1+s2;
//s3是串池中的 s4是在堆里面的 两个对象[new StringBuilder()| new String()]
System.out.println(s3==s4);//false
//直接去串池中找有没有ab,有的话用串池中有的,没有的话创建ab,放入串池
//javac 在编译期间的优化,结果已经在编译期间确定为ab
String s5="a"+"b";
System.out.println(s3==s5);//true
}
}
作者:
Darren
电话:15110448224
QQ:603026148
以上内容归
Darren
所有,如果有什么错误或者不足的地方请联系我
,希望我们共同进步。