JVM学习笔记

JVM

在这里插入图片描述
在这里插入图片描述

1、虚拟机栈

1. Java虚拟机栈也是线程私有的,它的生命周期与线程相同(随线程而生,随线程而灭)

2. 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常;

(当前大部分JVM都可以动态扩展,只不过JVM规范也允许固定长度的虚拟机栈)

3. Java虚拟机栈描述的是Java方法执行的内存模型:每个方法执行的同时会创建一个栈帧。

对于我们来说,主要关注的stack栈内存,就是虚拟机栈中局部变量表部分。

1.1、栈帧(Stack Frame)

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。它是虚拟机运行时数据区中的java虚拟机栈的栈元素。

栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。

每一个方法从调用开始至执行完成的过程,都对应着一个栈帧在虚拟机里面从入栈到出栈的过程。

口诀 filo first in last out

1.2局部变量表

1.局部变量表(Local Variable Table)是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。

并且在Java编译为Class文件时,就已经确定了该方法所需要分配的局部变量表的最大容量。

2.局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)「String是引用类型」,

对象引用(reference类型) 和 returnAddress类型(它指向了一条字节码指令的地址)

注意:

很多人说:基本数据和对象引用存储在栈中。

当然这种说法虽然是正确的,但是很不严谨,只能说这种说法针对的是局部变量。

局部变量存储在局部变量表中,随着线程而生,线程而灭。并且线程间数据不共享。

但是,如果是成员变量,或者定义在方法外对象的引用,它们存储在堆中。

因为在堆中,是线程共享数据的,并且栈帧里的命名就已经清楚的划分了界限 : 局部变量表!

1.3变量槽(Variable Slot)

局部变量表的容量以变量槽为最小单位,每个变量槽都可以存储32位长度的内存空间,例如boolean、byte、char、short、int、float、reference。

对于64位长度的数据类型(long,double),虚拟机会以高位对齐方式为其分配两个连续的Slot空间,也就是相当于把一次long和double数据类型读写分割成为两次32位读写。

1.4动态链接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,

持有这个引用是为了支持方法调用过程中的动态连接(Dynamic Linking)。

在类加载阶段中的解析阶段会将符号引用转为直接引用,这种转化也称为静态解析。

另外的一部分将在每一次运行时期转化为直接引用。这部分称为动态连接。

这里简单提一下动态连接的概念,后面在详细讲解.

1.5方法出口

当一个方法开始执行后,只有2种方式可以退出这个方法 :

方法返回指令 : 执行引擎遇到一个方法返回的字节码指令,这时候有可能会有返回值传递给上层的方法调用者,这种退出方式称为正常完成出口。

异常退出 : 在方法执行过程中遇到了异常,并且没有处理这个异常,就会导致方法退出。

无论采用任何退出方式,在方法退出之后,都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在栈帧中保存一些信息。

一般来说,方法正常退出时,调用者的PC计数器的值可以作为返回地址,栈帧中会保存这个计数器值。

而方法异常退出时,返回地址是要通过异常处理器表来确定的,栈帧中一般不会保存这部分信息。
栈,动态链接,方法出口

2、堆

arthas https://alibaba.github.io/arthas/

99.1、JAVA内存区域与内存溢出

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值