这篇文章将为大家详细讲解有关JVM程序计数器和栈的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
Java虚拟机在执行Java程序的过程中会它所管理的内存划分为若干不同的数据区域。上图是Java程序在运行时需要用的内存区域,其中本地内存不会由虚拟机管理而是直接由操作系统直接管理,其中绿色的内存区域是每个Java线程私有的,白色的内存区域是所有Java线程共享的。
由于Java程序在多线程执行的时候需要进行线程的切换,当线程进行切换的时候,需要记录当前线程执行字节码的位置,程序计数器保存了当前线程需要执行字节码的指令地址。
如果线程正在执行的一个Java方法,程序计数器记录的是正在执行的虚拟机字节码指令的地址,如果是一个Native方法,程序计数器值为空(Undefined)
Java栈是线程私有的内存空间,每一个Java方法的执行都会产生一个Java栈帧,当方法调用时栈帧会入栈,当方法返回时栈帧会出栈。在Java栈(准确的说是栈帧)中存放的主要有:
局部变量表用于保存函数的参数以及局部变量,存放了编译期可知的各种基本数据类型、对象引用(可能是一个指向对象起始地址的引用指针)或者是returnAddress类型(指向一条字节码指令的地址)。
public void stackSlot(int a, int b, long c) { { long d = 2; System.out.println(d); } StackObj obj = new StackObj(); int e = 3;}
局部变量表存在slot(index)的概念,上述代码的局部变量表如下:
局部变量表的变量是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象是不会被回收的。下面我们来分析一下局部变量表:
普通方法的局部变量表第一个slot(index为0的位置)都是this,表示指向自身,但是静态方法的局部变量表第一个slot就是第一个变量。
局部变量表中的slot是可以被重用的,仔细观察上图,会发现obj变量复用了变量d的slot。
操作数栈主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间
帧数据区保存中访问常量池的指针,以及异常处理表。异常处理表可以在程序遇到异常时,跳转到字节码的合适位置,如果无法在异常表中找到合适的处理方法,则会结束当前函数调用,并在调用函数中抛出相同的异常并且查找调用函数的异常表进行处理。
关于“JVM程序计数器和栈的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。