JVM的栈内存

目录

  • JVM栈之局部变量表:包含参数和局部变量
  • JVM栈之操作数栈
  • JVM栈之栈上分配(动态链连接)


  每当启动一个新线程时,Java虚拟机都会为它分配一个Java栈。Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈和出栈。

  某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。在线程执行一个方法时,它会跟踪当前类和当前常量池。此外,当虚拟机遇到栈内操作指令时,它对当前帧内数据执行操作。

  每当线程调用一个Java方法时,虚拟机都会在该线程的Java栈中压入一个新帧。而这个新帧自然就成为了当前帧。在执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等数据。

  Java方法可以以两种方式完成。一种通过return返回的,称为正常返回;一种是通过抛出异常而异常终止的。不管以哪种方式返回,虚拟机都会将当前帧弹出Java栈然后释放掉,这样上一个方法的帧就成为当前帧了。

  Java帧上的所有数据都是此线程私有的。任何线程都不能访问另一个线程的栈数据,因此我们不需要考虑多线程情况下栈数据的访问同步问题。当一个线程调用一个方法时,方法的的局部变量保存在调用线程Java栈的帧中。只有一个线程能总是访问那些局部变量,即调用方法的线程。

JVM栈之局部变量表:包含参数和局部变量

局部变量表存放了基本数据类型、对象引用和returnAddress类型(指向一条字节码指令的地址)。其中64位长度的long和double类型的数据会占用2个局部变量空间(slot)(下图1到3的原因),其余数据类型只占用1个。局部变量表所需的内存空间在编译期间完成分配。每个方法都对应一个栈帧。

public class StackDemo {

    //静态方法
    public static int runStatic(int i, long l, float f, Object o, byte b) {
        return 0;
    }

    //实例方法
    public int runInstance(char c, short s, boolean b) {
        return 0;
    }

}

其对应的局部变量表如下:

上方表格中,静态方法和实例方法对应的局部变量表基本类似。但有以下区别:实例方法的表中,第一个位置存放的是当前对象的引用。

JVM栈之操作数栈

Java没有寄存器,所有参数传递都是使用操作数栈。

public static int add(int a,int b){
        int c=0;
        c=a+b;
        return c;
    }

压栈的步骤如下:

  0:   iconst_0 // 0压栈

  1:   istore_2 // 弹出int,存放于局部变量2

  2:   iload_0  // 把局部变量0压栈

  3:   iload_1 // 局部变量1压栈

  4:   iadd      //弹出2个变量,求和,结果压栈

  5:   istore_2 //弹出结果,放于局部变量2

  6:   iload_2  //局部变量2压栈

  7:   ireturn   //返回

如果计算100+98的值,那么操作数栈的变化如下图所示:

JVM栈之栈上分配(动态链连接)

小对象(一般几十个bytes),在没有逃逸的情况下,可以直接分配在栈上

直接分配在栈上,可以自动回收,减轻GC压力

大对象或者逃逸对象无法栈上分配

本文内容来自:https://www.cnblogs.com/wade-luffy/p/5753057.html

原文地址:https://www.cnblogs.com/whu-2017/p/9629714.html

时间: 2024-10-07 09:42:09

JVM的栈内存的相关文章

Jvm(30),理解升级----Java中堆内存和栈内存详解

java中内存分配策略及堆和栈的比较 1 内存分配策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式 的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构 (比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求. 栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分

jvm 堆内存 栈内存 大小设置

  4种方式配置不同作用域的jvm的堆栈内存! 1.Eclise 中设置jvm内存: 修改eclipse的配置文件,对所有工程都起作用 修改eclipse根目录下的eclipse.ini文件 -vmargs  //虚拟机设置 -Xms40m //初始内存 -Xmx256m //最大内存 -Xmn16m //最小内存 -XX:PermSize=128M //非堆内存 -XX:MaxPermSize=256M  2.Eclise 中设置jvm内存:jres VM Arguments参数的设置,对所有

【转】jvm 堆内存 栈内存 大小设置

原文地址:http://blog.csdn.net/qh_java/article/details/46608395 4种方式配置不同作用域的jvm的堆栈内存! 1.Eclise 中设置jvm内存: 修改eclipse的配置文件,对所有工程都起作用 修改eclipse根目录下的eclipse.ini文件 -vmargs  //虚拟机设置 -Xms40m //初始内存 -Xmx256m //最大内存 -Xmn16m //最小内存 -XX:PermSize=128M //非堆内存 -XX:MaxPe

JVM的堆内存和栈内存中存储的数值或类型的区别在哪里

基本类型变量的值和内容是一致的引用类型变量的值在堆内存,赋值的内容是一个地址,这个地址也在栈内存,指向堆内存引用类型变量的值是内存地址,内存地址在栈内存,指向堆:内容是实例,在堆内存 引用类型变量时,栈内存存储的是指向堆的内存地址,真正数据在堆内存中,栈内存中存的是指向堆的地址,占用8个字节 类里面方法外的是成员方法跟属性(property),如果属性没有static修饰就是在堆,有即为静态属性(类属性)就不在,即在永久区,所有对象公用一份:eg:int i = 4,这个4 在栈内存 ,i是一个

JVM存储位置分配——java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配

Java中的变量根据不同的标准可以分为两类,以其引用的数据类型的不同来划分可分为“原始数据类型变量和引用数据类型变量”,以其作用范围的不同来区分可分为“局部变量,实例变量和静态变量”. 根据“Java中的变量与数据类型”中的介绍,“变量是在内存中分配的保留区域的名称.换句话说,它是一个内存位置的名称”,也就是说我们通过这个变量名字就可以找到一个指向这个变量所引用的数据的内存指针,根据变量的类型我们可以知道这个指针之后的几个字节里存储了这个变量所引用的数据. 所以,了解变量在方法区.栈内存.堆内存

Java 进阶(一) JVM运行时内存模型

1.JVM运行时数据区域的划分 a.程序计数器(Program Counter Register) 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.每个线程拥有独立的一个计数器,如果当前执行的是Native方法,则计数器值为空. b.JVM栈(Java Virtual Machine Stack) 描述Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stacks Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息. 每一个方法从调用直至执行完成

jvm运行时内存划分

(根据<深入理解java虚拟机>这本书总结) 本文主要解释jvm内存模型,以及各个部分的作用.都是自己总结的给自己看的通俗语言,未用专业术语的见谅. 一.为什么要了解jvm内存模型? 在了解一个类的编译-加载-内存分配-初始化所有过程前,要先了解jvm的内存模型.这样对整个java体系可能会更加便于理解.当然,如果不理解这些,也是没关系的,照样可以进行java开发. 二.jvm内存模型 1.根据自己的理解举个最简单的例子,一个main方法启动,进程运行,在这个过程中,会调用方法.开启多个线程.

java堆内存和栈内存的处理

前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题:删除节点的时候明明已经置null了可树上该节点依旧存在,还必须执行node.father.left = null;才可以删除node节点,寻找了一下原因发现还是因为对java内存管理理解不够深入. 代码如下: @Test public void testNode() { Node node1 = new Node("node1"); Node node2 = new Node("node2"); node2.

jvm运行时内存解析

一.jvm的概念 在了解jvm的概念之前,我们先来了解java平台的逻辑结构,图片来自<深入java虚拟机> 从图中我们可以看到jdk包含了jre,java语言和java开发工具和Api,jre包含了java运行的基础类库和java虚拟机,java虚拟机支撑着java程序的运行. jvm(java virtual machine)翻译为java虚拟机,从字面上来理解,jvm就是一个虚拟的机器,其实类似于一个操作系统,通过软件去虚拟出一个虚拟机,帮助我们管理计算机的内存和调用计算机的硬件等等.而