用Java实现JVM第四章《运行时数据区》

简介: 本案例初步实现运行时数据区里;线程、Java虚拟机栈、帧、操作数栈、局部变量表。

20.jpg

案例介绍

本案例初步实现运行时数据区里;线程、Java虚拟机栈、帧、操作数栈、局部变量表。

在运行Java程序时,Java虚拟机需要使用内存来存放各种各样的数据。Java虚拟机规范把这些内存区域叫作运行时数据区。运行时数据区可以分为两类:一类是多线程共享的,另一类则是线程私有的。多线程共享的运行时数据区需要在Java虚拟机启动时创建好在Java虚拟机推出时销毁。线程私有的运行时数据区则在创建线程时才创建,线程退出时销毁。

线程私有的运行时数据区用于辅助执行Java字节码。每个线程都有自己的pc寄存器(Program Counter)和Java虚拟机栈(JVM Stack)。Java虚拟机栈又由栈帧(Stack Frame,后面简称帧)构成,帧中保存方法执行的状态,包括局部变量表(Local Variable)和操作数栈(Operand Stack)等。在任一时刻,某一线程肯定是在执行某个方法。这个方法叫作该线程的当前方法;执行该方法的帧叫作线程的当前帧;声明该方法的类叫作当前类。如果当前方法是Java方法,则pc寄存器中存放当前正在执行的Java虚拟机指令的地址,否则,当前方法是本地方法,pc寄存器中的值没有明确定义。

Run-Time Data Area
├── Thread
│   └── pc
│   └── Jvm Stack
│       └── Frame
│           ├── Local Variable
│           └── Operand Stack
└── Heap
    ├── Method Area
    │   └── Class
    │       ├── Run-Time
    │       └── Constant Pool
    └── Object

环境准备

1、jdk 1.8.0

2、IntelliJ IDEA Community Edition 2018.3.1 x64

配置信息

1、调试配置

2.1、配置位置:Run/Debug Configurations -> program arguments

2.2、配置内容:-Xjre "C:\Program Files\Java\jdk1.8.0_161\jre" E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-04\target\test-classes\org\itstack\demo\test\HelloWorld

代码示例

itstack-demo-jvm-04
├── pom.xml
└── src
    └── main
    │    └── java
    │        └── org.itstack.demo.jvm
    │             ├── classfile
    │             │   ├── attributes   {BootstrapMethods/Code/ConstantValue...}
    │             │   ├── constantpool {CONSTANT_TAG_CLASS/CONSTANT_TAG_FIELDREF/CONSTANT_TAG_METHODREF...}
    │             │   ├── ClassFile.java
    │             │   ├── ClassReader.java
    │             │   └── MemberInfo.java
    │             ├── classpath
    │             │   ├── impl
    │             │   │   ├── CompositeEntry.java
    │             │   │   ├── DirEntry.java
    │             │   │   ├── WildcardEntry.java
    │             │   │   └── ZipEntry.java
    │             │   ├── Classpath.java
    │             │   └── Entry.java
    │             ├── rtda
    │             │   ├── Frame.java
    │             │   ├── JvmStack.java
    │             │   ├── LocalVars.java
    │             │   ├── OperandStack.java
    │             │   ├── Slot.java
    │             │   └── Thread.java
    │             ├── Cmd.java
    │             └── Main.java
    └── test
         └── java
             └── org.itstack.demo.test
                 └── HelloWorld.java

Frame.java

package org.itstack.demo.jvm.rtda;
/**
 * http://www.itstack.org
 * create by fuzhengwei on 2019/4/26
 * 栈帧
 */
public class Frame {
    //stack is implemented as linked list
    Frame lower;
    //局部变量表
    private LocalVars localVars;
    //操作数栈
    private OperandStack operandStack;
    public Frame(int maxLocals, int maxStack) {
        this.localVars = new LocalVars(maxLocals);
        this.operandStack = new OperandStack(maxStack);
    }
    public LocalVars localVars(){
        return localVars;
    }
    public OperandStack operandStack(){
        return operandStack;
    }
}

JvmStack.java

package org.itstack.demo.jvm.rtda;
/**
 * http://www.itstack.org
 * create by fuzhengwei on 2019/4/26
 * 虚拟机栈
 */
public class JvmStack {
    private int maxSize;
    private int size;
    private Frame _top;
    public JvmStack(int maxSize) {
        this.maxSize = maxSize;
    }
    public void push(Frame frame) {
        if (this.size > this.maxSize) {
            throw new StackOverflowError();
        }
        if (this._top != null) {
            frame.lower = this._top;
        }
        this._top = frame;
        this.size++;
    }
    public Frame pop() {
        if (this._top == null) {
            throw new RuntimeException("jvm stack is empty!");
        }
        Frame top = this._top;
        this._top = top.lower;
        top.lower = null;
        this.size--;
        return top;
    }
    public Frame top(){
        if (this._top == null){
            throw new RuntimeException("jvm stack is empty!");
        }
        return this._top;
    }
}

LocalVars.java

package org.itstack.demo.jvm.rtda;
/**
 * http://www.itstack.org
 * create by fuzhengwei on 2019/4/26
 * 局部变量表
 */
public class LocalVars {
    private Slot[] slots;
    public LocalVars(int maxLocals) {
        if (maxLocals > 0) {
            slots = new Slot[maxLocals];
            for (int i = 0; i < maxLocals; i++) {
                slots[i] = new Slot();
            }
        }
    }
    public void setInt(int idx, int val) {
        this.slots[idx].num = val;
    }
    public int getInt(int idx) {
        return slots[idx].num;
    }
    public void setFloat(int idx, float val) {
        this.slots[idx].num = (Float.valueOf(val)).intValue();
    }
    public Float getFloat(int idx) {
        int num = this.slots[idx].num;
        return (float) num;
    }
    public void setLong(int idx, long val) {
        this.slots[idx].num = (int) val;
        this.slots[idx + 1].num = (int) (val >> 32);
    }
    public Long getLong(int idx) {
        int low = this.slots[idx].num;
        int high = this.slots[idx + 1].num;
        return ((long) high << 32) | (long) low;
    }
    public void setDouble(int idx, double val) {
        setLong(idx, (long) val);
    }
    public Double getDouble(int idx) {
        return Double.valueOf(getLong(idx));
    }
    public void setRef(int idx, Object ref) {
        slots[idx].ref = ref;
    }
    public Object getRef(int idx) {
        return slots[idx].ref;
    }
}

OperandStack.java

package org.itstack.demo.jvm.rtda;
/**
 * http://www.itstack.org
 * create by fuzhengwei on 2019/4/26
 * 操作数栈
 */
public class OperandStack {
    private int size = 0;
    private Slot[] slots;
    public OperandStack(int maxStack) {
        if (maxStack > 0) {
            slots = new Slot[maxStack];
            for (int i = 0; i < maxStack; i++) {
                slots[i] = new Slot();
            }
        }
    }
    public void pushInt(int val) {
        slots[size].num = val;
        size++;
    }
    public int popInt(){
        size --;
        return slots[size].num;
    }
    public void pushRef(Object ref){
        slots[size].ref = ref;
        size++;
    }
    public Object popRef(){
        size --;
        Object ref = slots[size].ref;
        slots[size].ref = null;
        return ref;
    }
}

Slot.java

package org.itstack.demo.jvm.rtda;
/**
 * http://www.itstack.org
 * create by fuzhengwei on 2019/4/26
 * 数据槽
 */
public class Slot {
    int num;
    Object ref;
}

Thread.java

package org.itstack.demo.jvm.rtda;
/**
 * http://www.itstack.org
 * create by fuzhengwei on 2019/4/26
 * 线程
 */
public class Thread {
    //Program Counter 寄存器
    private int pc;
    //虚拟机栈
    private JvmStack stack;
    public Thread(){
        this.stack = new JvmStack(1024);
    }
    public int pc(){
        return this.pc;
    }
    public void setPC(int pc){
        this.pc = pc;
    }
    public void pushFrame(Frame frame){
        this.stack.push(frame);
    }
    public Frame popFrame(){
        return this.stack.pop();
    }
    public Frame currentFrame(){
        return this.stack.top();
    }
}

测试结果

100
-100
null
-100
目录
相关文章
|
27天前
|
监控 算法 Java
Java虚拟机(JVM)的垃圾回收机制深度解析####
本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
|
19天前
|
监控 算法 Java
Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
25 0
|
16天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
18天前
|
存储 监控 算法
Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
|
20天前
|
Java
JVM运行时数据区
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一
22 2
|
22天前
|
机器学习/深度学习 监控 算法
Java虚拟机(JVM)的垃圾回收机制深度剖析####
本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
31 1
|
22天前
|
Oracle 安全 Java
深入理解Java生态:JDK与JVM的区分与协作
Java作为一种广泛使用的编程语言,其生态中有两个核心组件:JDK(Java Development Kit)和JVM(Java Virtual Machine)。本文将深入探讨这两个组件的区别、联系以及它们在Java开发和运行中的作用。
48 1
|
26天前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
19 3
|
1月前
|
监控 Java 开发者
Java虚拟机(JVM)深度优化指南####
本文深入探讨了Java虚拟机(JVM)的工作原理及其性能优化策略,旨在帮助开发者通过理解JVM的内部机制来提升Java应用的运行效率。不同于传统的技术教程,本文采用案例分析与实战技巧相结合的方式,为读者揭示JVM调优的艺术。 ####
58 8
|
2月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
39 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
下一篇
DataWorks