`
jerrycaoyong
  • 浏览: 2682 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

JVM栈(JVM 二) -转载自躁动的绵羊

    博客分类:
  • JVM
阅读更多

  java栈概述

 

       记得当初我学习java时,常常听见身边的朋友说:“你要记住,当new一个对象时,对象的引用存放在栈里,而对象是存放在堆里的。当时,听到这句教导时,脑海里立即出现栈的模型——里面存的仅仅是个引用。最近,看了下《深入JVM,才发现,原来栈并不是我想象的那么简单,它和我想象中的那个栈的结构差别非常大。

     每当启用一个线程时,JVM就为他分配一个JAVA栈,栈是以帧为单位保存当前线程的运行状态。某个线程正在执行的方法称为当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。当线程执行一个方法时,它会跟踪当前常量池。

     每当线程调用一个java方法时,JVM就会在该线程对应的栈中压入一个帧,这个帧自然就成了当前帧。当执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等。

java栈上的所有数据都是私有的。任何线程都不能访问另一个线程的栈数据。所以我们不用考虑多线程情况下栈数据访问同步的情况。

像方法区和堆一样,java栈和帧在内存中也不必是连续的,帧可以分布在连续的栈里,也可以分布在堆里

 

java栈的组成元素——栈帧

 

栈帧由三部分组成:局部变量区、操作数栈、帧数据区。局部变量区和操作数栈的大小要视对应的方法而定,他们是按字长计算的。但调用一个方法时,它从类型信息中得到此方法局部变量区和操作数栈大小,并据此分配栈内存,然后压入Java栈。

 

局部变量区 局部变量区被组织为以一个字长为单位、从0开始计数的数组,类型为shortbytechar的值在存入数组前要被转换成int值,而longdouble在数组中占据连续的两项,在访问局部变量中的longdouble时,只需取出连续两项的第一项的索引值即可,如某个long值在局部变量区中占据的索引时34项,取值时,指令只需取索引为3long值即可。

     说再多也没用,下面就看个例子,好让大家对局部变量区有更深刻的认识。这个图来着《深入JVM》:

      

Java代码 复制代码
  1. public static int runClassMethod(int i,long l,float f,double d,Object o,byte b) {   
  2.         return 0;   
  3.     }   
  4.        
  5.     public int runInstanceMethod(char c,double d,short s,boolean b) {   
  6.         return 0;   
  7.     }  
public static int runClassMethod(int i,long l,float f,double d,Object o,byte b) {
		return 0;
	}
	
	public int runInstanceMethod(char c,double d,short s,boolean b) {
		return 0;
	}

 

    上面代码片的方法参数和局部变量在局部变量区中的存储结构如下图:

   

      

上面这个图没什么好说的,大家看看就会懂。但是,在这个图里,有一点需要注意:

 runInstanceMethod的局部变量区第一项是个reference(引用),它指定的就是对象本身的引用,也就是我们常用的this,但是在runClassMethod方法中,没这个引用,那是因为runClassMethod是个静态方法

   

    操作数栈  和局部变量区一样,操作数栈也被组织成一个以字长为单位的数组。但和前者不同的是,它不是通过索引来访问的,而是通过入栈和出栈来访问的。可把操作数栈理解为存储计算时,临时数据的存储区域。下面我们通过一段简短的程序片段外加一幅图片来了解下操作数栈的作用。

     int a = 100;

    int b = 98;

    int c = a+b;

    

 

    从图中可以得出:操作数栈其实就是个临时数据存储区域,它是通过入栈和出栈来进行操作的。

  

   

      帧数据区   除了局部变量区和操作数栈外,java栈帧还需要一些数据来支持常量池解析、正常方法返回以及异常派发机制。这些数据都保存在java栈帧的帧数据区中。

    JVM执行到需要常量池数据的指令时,它都会通过帧数据区中指向常量池的指针来访问它。

     除了处理常量池解析外,帧里的数据还要处理java方法的正常结束和异常终止。如果是通过return正常结束,则当前栈帧从Java栈中弹出,恢复发起调用的方法的栈如果方法又返回值,JVM会把返回值压入到发起调用方法的操作数栈

    为了处理java方法中的异常情况,帧数据区还必须保存一个对此方法异常引用表的引用。当异常抛出时,JVMcatch块中的代码。如果没发现,方法立即终止,然后JVM用帧区数据的信息恢复发起调用的方法的帧。然后再发起调用方法的上下文重新抛出同样的异常

 

   

   栈的整个结构

  

  在前面就描述过:栈是由栈帧组成,每当线程调用一个java方法时,JVM就会在该线程对应的栈中压入一个帧,而帧是由局部变量区、操作数栈和帧数据区组成。那在一个代码块中,栈到底是什么形式呢?下面是我从《深入JVM》中摘抄的一个例子,大家可以看看:

 

   代码片段:

  

  

     执行过程中的三个快照:

   

 

  上面所给的图,只想说明两件事情:

   1.  只有在调用一个方法时,才为当前栈分配一个帧,然后将该帧压入栈

   2.  帧中存储了对应方法的局部数据,方法执行完,对应的帧则从栈中弹出,并把返回结果存储在调用 方法的帧的操作数栈中

 

分享到:
评论

相关推荐

    JVM调优总结 -Xms -Xmx -Xmn -Xss

    JVM调优总结 -Xms -Xmx -Xmn -Xss JVM 调优是 Java virtual machine 的性能优化,通过调整 JVM 的参数来提高 Java 应用程序的性能。其中,-Xms、-Xmx、-Xmn、-Xss 是四个重要的参数,分别控制 JVM 的初始堆大小、...

    第3节: 揭秘JVM运行时数据区-02

    第3节: 揭秘JVM运行时数据区-02第3节: 揭秘JVM运行时数据区-02第3节: 揭秘JVM运行时数据区-02第3节: 揭秘JVM运行时数据区-02第3节: 揭秘JVM运行时数据区-02第3节: 揭秘JVM运行时数据区-02第3节: 揭秘JVM运行...

    nginx-upstream-jvm-route-1.15

    【标题】"nginx-upstream-jvm-route-1.15" 涉及的核心知识点是Nginx的upstream模块与JVM路由的整合,特别针对Nginx 1.15版本。这个项目旨在解决在配置Nginx时遇到的特定错误提示“nginx: [emerg] invalid parameter ...

    metrics-jvm-3.1.5-API文档-中文版.zip

    赠送jar包:metrics-jvm-3.1.5.jar; 赠送原API文档:metrics-jvm-3.1.5-javadoc.jar; 赠送源代码:metrics-jvm-3.1.5-sources.jar; 赠送Maven依赖信息文件:metrics-jvm-3.1.5.pom; 包含翻译后的API文档:...

    JVM图解-JVM指令-JVM原型图.rar

    在这个压缩包中,"JVM图解.png"可能是对JVM内部结构的可视化表示,"JVM图解"可能是一个详细的文档,解释了JVM的工作原理,而"JVM指令手册 中文版"则提供了JVM可执行的所有指令的详细信息。下面,我们将深入探讨JVM的...

    java jvm 参数 -Xms -Xmx -Xmn -Xss -

    这些参数是用来调整JVM堆内存和线程栈大小的。 1. `-Xms`: 这个参数用于设置JVM启动时初始的堆内存大小。默认情况下,JVM会从小到大动态地调整堆空间,但设置`-Xms`可以确保程序启动时就分配足够的内存,避免频繁的...

    JVM调优总结 Xms -Xmx -Xmn -Xss

    ### JVM调优总结:Xms、Xmx、Xmn、Xss 在Java虚拟机(JVM)的运行过程中,合理的参数配置对于提高程序性能至关重要。本文将对JVM调优中的几个关键参数进行深入解析,包括-Xms、-Xmx、-Xmn和-Xss等,帮助开发者更好...

    Jvm调优练习-jvm-tuning.zip

    【标题】"Jvm调优练习-jvm-tuning.zip" 提供了一个实践 JVM(Java Virtual Machine)调优的机会,这是一项至关重要的技能,特别是在处理大型、高性能的Java应用程序时。JVM调优涉及到调整一系列参数,以优化应用程序...

    SAP JVM 8.1 64 bits

    SAP JVM 8.1 64位是一个专为SAP系统设计的Java虚拟机,它基于Oracle的Java Development Kit (JDK) 进行优化,以满足SAP应用程序的特定需求。SAP JVM旨在提高性能、可靠性和安全性,同时确保与SAP产品的无缝集成。...

    JVM-java-springboot-demo.zip

    JVM-java-springboot-demo.zip

    jvm-nmt-tracing-master.zip

    这个名为"jvm-nmt-tracing-master.zip"的压缩包可能包含一个Python项目,用于帮助开发者利用NMT进行JVM内存分析。Python在数据处理和自动化方面具有强大能力,可以很好地与JVM的诊断工具结合,如jinfo、jmap和jcmd,...

    mini-jvm in rust实现jvm,jvm-rs-main.zip

    二、理解Mini-JVM Mini-JVM是JVM的简化版本,它通常只包含JVM的基本功能,如类加载、字节码解释执行等。通过实现Mini-JVM,开发者可以更直观地理解JVM如何执行字节码,如何管理内存,以及如何实现垃圾回收等关键...

    JVM调优的测试项目-JVM-subject.zip

    "JVM调优的测试项目-JVM-subject.zip"是一个专门针对JVM优化的实践项目,其内容可能包含了各种测试场景和调优策略。在这个项目中,我们可以学习到以下几个关键的知识点: 1. **JVM内存模型**:JVM内存分为堆内存...

    jvm性能调优-jvm内存模型和优化-performance-jvm-memorymodel-optimize.zip

    《JVM性能调优:深入理解JVM内存模型与优化》 在Java开发中,JVM(Java Virtual Machine)性能调优是提升应用程序效率的关键环节。JVM内存模型的理解和优化,对于解决性能瓶颈、避免内存泄漏以及提高系统稳定性至关...

    生产环境jvm调优的实例代码-jvm.zip

    这里我们将详细探讨这些关键知识点,并结合提供的"生产环境jvm调优的实例代码-jvm.zip"中的内容进行深入讲解。 1. **内存配置**:JVM内存分为新生代(Young Generation)、老年代(Tenured Generation/老年代)和...

    metrics-jvm-3.1.5-API文档-中英对照版.zip

    赠送jar包:metrics-jvm-3.1.5.jar; 赠送原API文档:metrics-jvm-3.1.5-javadoc.jar; 赠送源代码:metrics-jvm-3.1.5-sources.jar; 赠送Maven依赖信息文件:metrics-jvm-3.1.5.pom; 包含翻译后的API文档:...

    jvm基础知识与调优-jvm-training.zip

    这个“jvm-training”资料包涵盖了JVM的核心概念、内存管理、垃圾回收机制、性能优化等方面的知识。 1. **JVM架构** - 类加载器:JVM通过类加载器将.class文件加载到内存,分为引导类加载器、扩展类加载器和应用...

    JVM 参数调优-optimization-jvm.zip

    "JVM 参数调优-optimization-jvm.zip"这个压缩包很可能是包含了一套关于JVM调优的资料或者代码示例,可能包括文档、教程或工具。虽然具体的文件内容未给出,但我们可以根据标题和描述来讨论JVM调优的一些关键知识点...

    JVM的调优总结----------

    ### JVM调优总结 #### 1. JVM配置 在Java应用程序的运行过程中,JVM(Java虚拟机)扮演着至关重要的角色。为了确保应用程序能够高效稳定地运行,正确配置JVM参数至关重要。以下是一些常见的JVM配置参数及其含义: ...

    nginx-upstream-jvm-route 和 nginx 对应版本,亲测可用

    此资源有两个文件,含 nginx-upstream-jvm-route 和 nginx 对应版本,都是tar.gz文件。 安装方法网上很多就不写了,亲测可用。 不用担心版本不匹配造成安装失败,再浪费积分去到处下载尝试的烦恼。 此资源有两个文件...

Global site tag (gtag.js) - Google Analytics