jvm-tow

作者: 何德何能者 | 来源:发表于2019-07-17 18:41 被阅读0次

    JVM的各种内存区域

    每当java虚拟机运行程序时,它需要内存来存储许多东西,包括字节码和从加载的类文件中提取的其他信息,程序实例化的对象,方法的参数,返回值,局部变量和计算的中间结果。Java虚拟机将执行程序所需的内存组织到多个运行时数据区域中。

    • 方法区
    • 堆区
    • 堆栈区
    • PC注册
    • 本地方法堆栈

    1 方法区

    • 对于每个JVM,都只有一个方法区;
    • JVM启动时创建方法区;
    • 存储类级别的字节码数据,包括静态变量;
    • 类的常量池也在方法区中;
    • 方法区可用被多线程访问,线程安全;
    • 方法区的大小无需修改,再jvm运行时,虚拟机可用扩展和收缩方法区的大小;

    2 堆区

    • 每个JVM,都只有一个堆区;
    • 再JVM启动时创建堆;
    • 对象实例和相应的变量将存储再堆区域中;
    • 堆区可用由多线程访问,线程不安全;
    • 堆区内存地址不要求连续;
      Java应用程序可用通过Runtime对象获取堆的内存信息;
      1.maxMemory()返回分配的最大内存字节数;
      2.totalMemory()返回总分配的内存字节数;
      3.freeMemory()返回堆内存可用字节数;

    3 堆栈

    对于每个线程,JVM将在创建线程时创建运行时堆栈;线程执行的每个方法调用和响应的局部变量都将存储在堆栈中;
    对于每个方法的调用,将想堆栈添加单独的条目,我们称之为“堆栈帧”或者“活动记录”方法完成调用后,相应的帧将从堆栈中删除。在完成所有方法调用后,堆栈将变为空,并且在终止线程之前,JVM将销毁改空堆栈; 存储在堆栈中的数据对应的线程时私有的.

    jvm_stack2.png

    堆栈的结构包含3个部分
    1、局部变量数组;
    2、操作数堆栈;
    3、帧数据;
    局部变量数组
    它包含方法的所有参数和局部变量。数组中的每个槽都是4个字节;

    • int, float,boolean和reference类型的值占用1个槽;
    • long,double类型的值占用2个槽;
    • byte,short, char的值被转换成int类型并占用1个槽;
      jvm堆栈局部变量数组.png
      操作数堆栈
    • 某些指令可用将值推送到操作数堆栈,一些指令执行所需操作,一些指令存储结果等。
    • 操作数堆栈遵循先进后出(LIFO)方式;
      例如,iadd指令通过从操作数堆栈的顶部弹出两个整数,相加后又推送结果到堆栈;以下是java虚拟机如何添加包含int的两个局部变量并将结果存储在第三个变量中;
      jvm操作数堆栈2.png
      帧数据
      除了局部变量和操作数堆栈外,java堆栈帧还包含支持常量池解析的数据,已该法方的所有符号引用,常规方法返回和异常分派;这部分数据存储在java堆栈帧的帧数据部分。它包含一个引用的异常表,它包含异常情况下相应的catch快信息。当方法抛出异常时,java虚拟机使用帧数据引用的异常表来确定如何处理异常.
      PC寄存器
      对应每个线程,在创建线程时将创建单独的pc寄存器。pc寄存器包含当前执行指令的地址。一旦指令执行自动完成。pc寄存器将递增已保存下一条指令地址。“地址"可用是本机指针,也可以是方法字节码开头的偏移量。
      本地方法堆栈
      每个线程创建一个单独的运行时堆栈。它包含应用程序中使用的所有本地方法。Native方法是指用java以外的语言编写的方法。换句话说,它是用于执行通过JNI调用的c/c++代码的堆栈;
      当线程调用java方法时,虚拟机会创建一个新帧并推送到java堆栈。但是,当线程调用本地方法时,该线程将会留下java堆栈。java虚拟机不是将新帧推送到线程的java堆栈上,而是简单的动态链接并直接调用本机方法.
      jvm本地方法堆栈.png

    转载翻译:https://www.waytoeasylearn.com/2016/06/jvm-tutorial-part-2.html

    相关文章

      网友评论

          本文标题:jvm-tow

          本文链接:https://www.haomeiwen.com/subject/vdmclctx.html