JAVA学习笔记(1)——JVM内存模型

JVM内存模型

  • JVM,即Java虚拟机,其内存空间分为五个部分,分别为:

    • 程序计数器 (线程私有)
    • Java虚拟机栈 (线程私有)
    • 本地方法栈 (线程私有)
    • (线程共享)
    • 方法区 (线程共享)
  • 程序计数器

    • 需要注意的是,与计算机中真正的程序计数器PC不同,JVM中的程序计数器是线程私有的,即每条线程都有一个程序计数器。
    • 在多线程的情况下,程序计数器用于记录当前线程执行的位置,线程切换回来时通过程序计数器得知当前线程运行到了哪里。
    • 如果当前线程正在执行的是一个本地方法,那么此时程序计数器为空。
  • Java虚拟机栈

    • Java虚拟机栈是描述Java方法运行过程的内存模型。

    • 当一个方法即将被运行时,Java虚拟机栈首先会在Java虚拟机栈中为该方法创建一块“栈帧”,栈帧中包含局部变量表、操作数栈、动态链接、方法出口信息等当方法在运行过程中需要创建局部变量时,就将局部变量的值存入栈帧的局部变量表中

      • 局部变量表:局部变量表(Local Variable Table)是一组变值存储空间,用于存放方法参数和方法内部定义的局部变量。作用上基本相当于计算机系统中的栈帧的主要部分,即局部变量的存储和修改。局部变量表所需的容量大小是在编译期确定下来的,在方法运行期间是不会改变局部变量表的大小的。

      • 操作数栈:主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。操作数栈就是JVM执行引擎的一个工作区,当一个方法刚开始执行的时候,这个方法的操作数栈是空的。

      • 动态链接:在一个class文件中,一个方法要调用其他方法,需要将这些方法的符号引用(即方法名)转化为其在内存地址中的直接引用(即内存地址),而符号引用存在于方法区中的运行时常量池。Java虚拟机栈中,每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,持有这个引用的目的是为了支持方法调用过程中的动态连接。(//…如何支持的动态链接?)

    • 当这个方法执行完毕后,这个方法所对应的栈帧将会出栈,并释放内存空间。

  • 本地方法(native method)栈

    • 什么是“本地方法”

      • 简单地讲,一个Native Method就是一个java调用非java代码的接口。

      • 在定义一个native method时,并不提供实现体,因为其实现体是由非java语言在外面实现的。例:

        public class Test{
            native public void Native1(int x);
            native synchronized private float Native3(Object o) ;
        }
        
        
      • 如果一个方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针。这些实现在一些DLL文件(Windows系统)内,但是它们会被操作系统加载到java程序的地址空间。

      • 本地方法地方法保存在动态链接库中,即.dll(windows系统)文件中,格式是各个平台专有的。故JAVA方法是与平台无关的,但是本地方法不是。(JAVA中有两种方法:JAVA方法和本地方法)

    • 本地方法栈和Java虚拟机栈实现的功能类似,只不过本地方法区是本地方法运行的内存模型。

    • 本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

    • 堆是用来存放对象的内存空间,几乎所有的对象都存储在堆中(JVM可能会通过逃逸分析技术,对于逃不出方法的对象,会让其在栈空间上进行分配。)。

    • 堆是垃圾回收的主要场所,并继续细分为新生代、老年代等不同区域,不同的区域存放具有不同生命周期的对象。这样可以根据不同的区域使用不同的垃圾回收算法,从而更具有针对性,从而更高效。

    • 堆的大小既可以固定也可以扩展,但主流的虚拟机堆的大小是可扩展的,因此当线程请求分配内存,但堆已满,且内存已满无法再扩展时,就抛出OutOfMemoryError

  • 方法区

    • Java虚拟机规范中定义方法区是堆的一个逻辑部分。

    • 方法区中的信息一般需要长期存在,而且它又是堆的逻辑分区,因此用堆的划分方法,我们把方法区称为老年代。对方法区的内存回收的主要目标是:对常量池的回收和对类型的卸载。

    • 方法区中存放三种数据:类信息、常量、静态变量、即时编译器编译后的代码。其中常量存储在运行时常量池中。

    • 运行时常量池:

  • 直接内存:直接内存是除Java虚拟机之外的内存,但也有可能被Java使用。

参考资料:

深入理解JVM(一)——JVM内存模型_凌澜星空的博客-CSDN博客_jvm内存模型

JVM-本地方法_xlshi1996的博客-CSDN博客_jvm如何执行本地方法

JVM栈- 局部变量表 - 简书 (jianshu.com)

Java虚拟机—栈帧、操作数栈和局部变量表 - 简书 (jianshu.com)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值