jvm
2018-08-23 15:01:25 3 举报
jvm 运行数据和内存模型
作者其他创作
大纲/内容
每个线程都有一个程序计数器
操作栈表
1
由root指向时不被回收
虚拟机栈
AB
getList() 方法2
局部变量表
本地方法栈
A引用B,B引用A则不会被回收
出口
区域二
a
gcroot
c
指令
1s1
程序计数器
obj引用类型
复制回收算法:空间一分为二,开辟空间在区域一开辟,区域二不开辟,等到区域一满了,回收区域一,回收不了的放入区域二中,这个算法缺点在于,空间1:1,相当于区域二没有利用,加入1g的内存条,相当于只用了512M,另外的512M废了。
动态链接
c被回收
新生代
老年代
8
永久代
$ javap -c -v JVMTest.class p.txt
1s2
方法区
栈帧
jdk小于1.8
8M
jvm内存模型 jmm
动态链接:@atuowried UserServer userServeiceprivate void go(){userService.go();}当没有执行到go方法时。userService.go();就是普通语句。当执行时就会去常量池总找对应的实例运行(15: invokevirtual #5 // Method getList:()V (本行虚拟机站中) #5 = Methodref #9.#33 // test/JVMTest.getList:()V)。(本行在常量中)(常量池在javap -c -v 后文件的最上方)我理解常量池存放一些类的全限定名。常量池并不是放的常量
对于方法区的回收:1.当常量池中假如有一个字符串\"abc\",但在系统中没有一个对象叫做abc,这样将被清理,常量池中的类(接口),方法,字段的符号引用也是类似2判断一个类是否为无用的类(1).该类所有的实例都已经被回收,也就是java堆中不存在不存在该类的实例(2)。该类的的ClassLoader已经被回收(3)。该类对应的java.lang.Class对象没有在任何地方被应用,无法在任何地方通过反射访问该类的方法。
int
堆
线程B
8 :1 :1
public class JVMTest { //成员变量 private Object o=new Object(); //局部变量 public void queryById(){ int i=0; int j=1; int z=i+j; Object ob=o; getList(); } public void getList(){ System.out.print(\"123\"); }}
文本
meta space
obj
本地方法栈:和虚拟站相同,运行的jvm本地的方法,system等
什么样的对象应该被GC
当用可达性分析时,这种情况就被回收了,因为没有root指向
存储局部变量,编译的时候已经定义好大小,他是一个定长的区域,32位(八大类型和引用类型)
操作栈相当于在运行局部变量表,(从局部变量表中存取,运算)
虚拟机栈:存储当前线程运行方法所需的数据,指令,返回地址
数据
0:iconst_0 将int类型常量0压入栈(虚拟机栈)1:istore_1 将int类型值存入局部变量1 2:iconst_1 将int类型常量1压入栈(虚拟机栈)3:istore_2 将int类型值存入局部变量2 4:iload_1 从局部变量1中装载int类型值(操作栈) 5:iload_2 从局部变量2中装载int类型值(操作栈)6:iadd 执行int类型的加法(操作栈)
默认新生代和老年代是1:2他是会自动调节的
b
程序计数器:指向当前线程正在执行的字节码指令的地址,行号。当前指令已经再执行为何还要记录其地址呢?因为我们的方法执行在线程上,线程运行在cpu上,cup执行策略是时间片轮换,所以可能线程执行一半就去执行别的线程,当回过来执行另一半的时候通过程序计数器寻找指令。程序计数器在编译的时候已经完成了此内存区域是唯一一个java虚拟机规范中没有规定outofMemoryError的情况
1.8
如何实现判断死活算法和垃圾收集算法1.枚举根节点2.安全点3.安全域
当线程调用方法1时候压入虚拟机栈
BA
JVM运行时数据区
queryById() 方法1
线程A
区域一
那些可以成为可达性分析算法的root1.虚拟机栈中的变量表引用的对象(例如压入栈中的方法中变量,回收了还运行个球啊)2.方法区中类静态变量引用的对象,常量引用的对象3.本地方法栈中jni引用的对象(同1)
gc算法1.引用计算法2:可达性分析
0 条评论
下一页