/**
     * java虚拟机规范
     *      虚拟机结构
     *          @class文件格式
     *              javac编译后生成的class格式文件,使用一种平台中立的格式表示
     *              class文件中精确定义了类与接口的表示形式,包括平台相关的目标文件格式的一些细节。
     *
     *          @数据类型
     *              原始类型(原始值),引用类型(引用值)
     *                  变量赋值,参数传递,方法返回和运算操作
     *
     *          java虚拟机希望尽可能多的类型检查能够在运行之前完成——编译器期间尽最大助力完成类型检查
     *          原始类型可以直接通过字节码指令直接区分是属于什么类型——iadd,ladd,fadd,dadd
     *
     *          java虚拟机是直接支持对象,可以是动态分配的某个类的实例,也可以是某个数组
     *              @reference 类型指向对象的指针
     *
     *          @原始类型和值
     *              java虚拟机原始类型 ——数值类型 数值类型又有整数类型和浮点类型
     *                                  boolean类型 默认false
     *                                  returnAddress类型 指向某个操作码的指针,此操作与虚拟机指令相对应
     *
     *          @运行时数据区
     *              @java虚拟机定义了若干种程序运行期间会用到的运行时数据区,
     *                  其中一些会随着虚拟机的创建而创建,随着虚拟机的退出而销毁。
     *              @另一些则是和线程一一对应,随着线程的开始和结束而创建和销毁。
     *
     *              @PC寄存器(program counter)
     *                  jvm可以同时支持多条线程运行,每个线程都有自己的pc寄存器
     *                  任意时刻,jvm线程只会执行一个方法的代码,这个正在被线程执行的方法称为该线程的当前方法
     *                  如果这个方法不是native,pc寄存器保存jvm正在执行字节码指令的地址
     *                  如果是native,pc寄存器的值是undefined
     *                  @pc寄存器的容量应当至少能够保存一个returnAddress类型的数据或者一个平台相关的本地指针的值
     *
     *              @jvm栈
     *                  每一条java虚拟机线程都有自己的私有虚拟机栈,这个栈和线程同时创建,用于存储栈帧。
     *                  java虚拟机栈的作用于存储局部变量与一些尚未算好的结果。在方法调用和返回中也扮演了重要的角色。
     *                  除了栈帧的出栈入栈外。java虚拟机栈不会再受其他影响,所以栈帧可以在堆中分配。
     *                  java虚拟机栈所使用的内存不需要保证是连续的。
     *                  --
     *                 java虚拟机栈被实现为固定大小,也允许根据计算动态来扩展和收缩,
     *                 如果固定大小的虚拟机栈,每个线程的java虚拟机栈容量可以在线程创建的时候独立选定。
     *                  --
     *                  Java虚拟机栈可能发生的异常情况
     *                      @如果线程请求分配的栈容量超过java虚拟机栈的允许的最大容量,
     *                          java虚拟机会抛出一个StackOverflowError异常
     *                      @如果java虚拟机栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存
     *                          或者在创建新的线程时没有足够的内存去创建对应的虚拟机栈,
     *                          java虚拟机会跑出一个OutOfMemoryError异常
     *
     *              @java堆
     *                  在java虚拟机中,堆是可供各个线程共享的运行时内存区域。
     *                  也是供所有类实例和数组对象分配内存的区域。
     *
     *                  java堆在虚拟机启动时候被创建。它存储了被自动内存管理系统GC所管理的对象。
     *                  这些管理的对象无法显式的进行销毁。
     *                  java堆的容量是可以固定。也可以随着程序的执行动态扩展,并在不需要过多空间时自动收缩。
     *                  java堆所使用的内存不需要保证是连续的。指针指向下一个块的作用
     *
     *                  java堆发生的异常
     *                      如果实际所需要的堆超过了gc系统提供的最大容量,则抛出OutOfMemoryError
     *
     *              ------------java 栈和堆 的概念和 传统的堆和栈的概念区分开。
     *
     *              @方法区
     *                  在java虚拟机中,方法区(method area)是提供各个线程共享的运行时内存区域
     *                  存储一个类的结构信息
     *                      例如,运行时常量池(runtime constant pool),字段和方法数据,构造函数和普通方法的字节码内容
     *                          还包括在类,实例,接口初始化时用到的特殊方法
     *                  方法区在java虚拟机启动时创建,虽然方法区是堆逻辑组成部分,但是简单的虚拟机实现可以选择在这个区域不实现GC与压缩
     *
     *                      异常 OutOfMemoryError是怎么发生的?
     *
     *              @运行时常量池(runtime constant pool)
     *                  是class文件中每个类或接口的常量池表的运行时表示形式。
     *                  包含了若干种不同的常量,从编译期可知的数值字面量到必须在运行期解析后才能获得的方法和字段引用。
     *                  每一个运行时常量池都在java虚拟机的方法区中分配。在加载类和接口到虚拟机后就创建对应的运行时常量池。
     *                  $当创建类和接口时,如果构造运行时常量池所需要的内存空间超过了方法区所能提供的最大值,抛出异常
     *                      OutOfMemoryError
     *
     *              @本地方法栈
     *                  java虚拟机实现可能会用到传统的栈(C Stack)来支持native方法执行(使用其他语言编写的方法)
     *                  如果支持本地方法栈,这个栈会在线程创建时候按照线程分配。
     *                  java虚拟机规范允许本地方法栈实现固定大小或者根据计算动态扩展。
     *                  异常
     *                      StackOverflowError
     *                      OutOfMemoryError
     */