一篇文章带你领略——JVM运行原理揭秘

JVM运行时数据区

d57cba8b228695984b865c4187a4587b39f.jpg

线程共享所有线程能访问这块内存数据,随虚拟机或GC而创建和销毁

线程独占每个线程都会有它独立的空间,随线程生命周期而创建和销毁

线程安全问题:共享资源的抢占、线程共享的内存区域

方法区

c39b71231d9b4e77b95a39fefa3f1ea6fef.jpg

方法区作用:存储加载的类信息、常量、静态变量、JIT编译后的代码等数据

GC:方法区存在垃圾回收,但回收效率低;回收主要针对常量池的回收。和类型的卸载;当方法区无法满足内存需求时,报OOM。

方法区属于Java虚拟机协议,比如Hotsport虚拟机是对其具体实现,实现的时候会去实现方法区,堆内存,垃圾回收GC,永久代是对方法区的实现,新生代,老年代对堆内存实现,jdk1.8就变了,以元数据来实现方法区。

堆内存

654d875641ac5eea10942f0ee7716a70d4b.jpg

作用:唯一的目的就是存放对象实例,几乎所有对象、数组都是在这里存放

对于大多数应用来说,堆是JVM管理的内存中最大的一块内存区域,也是最容易OOM的区域

大多数JVM都将堆实现为大小可扩展的(通过-Xmx、-Xms)控制

思考问题一:堆中存储了对象,那到底存储了什么?

Java对象在内存中的布局

ebf54d9acc6ed87fb19730454247ef9c85f.jpg

思考问题二:对象何时被回收?

1、引用计数法(无法解决两个对象相互引用无法回收问题,导致内存泄露,JVM肯定不回去使用这种方式)

63414fd3881122a4213e35a760cfc9757a4.jpg

2、可达性分析算法

88000bf57c29736858f2e0e3fe008be6cdc.jpg

主流的商用程序语言(Java、C#)都是通过可达性分析算法来判定对象是否存活的,

GC Roots可以是:1、虚拟机栈;2、方法中静态属性引用对象;3、方法区中常量引用对象;4、Native方法引用对象。

虚拟机栈

ff9037bce8f48af45ca5ded6e8e68ba324c.jpg

虚拟机栈:线程中方法执行的模型,每个方法执行时,就会在虚拟机栈中创建一个栈帧,每个方法从调用到执行的过程,就对应栈帧在虚拟机栈中从入栈到出栈过程。

Java线程本质是:从逻辑上来理解,开启一个Java线程,new Thread(()->{线程执行的业务代码})

main->show()->show1()->shou2()这样的调用链路,先进后出,就是,也就是代表虚拟机栈方法调用逻辑

虚拟机栈中的元素在逻辑上代表方法,代表方法的栈元素就叫做栈帧。

局部变量表

1555ba25f67203c0edc020c60eaa7bab426.jpg

动态链接

方法里的局部变量并不是一致存在,只有在方法调用的时候才会存在,只有在方法调用才会有方法入栈。

b193bfba39ebe8304d8407beb5c72572eb7.jpg

返回值地址

70fa9e5ab3406555f9a229c3c90dc483756.jpg

本地方法栈、直接内存

4dc11e2190c0fb1d4e80711ec5ab0725178.jpg

本地方法栈:和虚拟机栈功能类似,虚拟机栈是为虚拟机执行Java方法而准备,本地方法栈是为虚拟机使用Native本地方法而准备的。

直接内存:JVM之外的内存,开发人员自己分配内存

class文件结构

8d64c19c89d2284d6919cba1cf8536918e1.jpg

现在看下整个过程执行流程

80a9d380bdb109340a69f191631288dd405.jpg

0338dc23f6b283f9a8b1213e970db8e67d6.jpg

切换上下文方式,程序计数器来跟踪。

 

转载于:https://my.oschina.net/u/3995125/blog/3094008

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值