zoukankan      html  css  js  c++  java
  • 【Java】JVM内存模型解析

     JVM内存模型主要分为五大区域:栈、堆、本地方法栈、程序计数器、方法区。

    本地方法栈:

    跟虚拟机栈非常相似,也是线程私有的,不过虚拟机栈是针对Java方法,而本地方法栈是针对native方法,也就是底层方法。

    由于Java是跨平台语言,导致的它不得不牺牲一些对底层方法的控制,而要实现这些底层方法的控制,就需要用到native方法,而本地方法栈就是针对native方法的。

    程序计数器:

    每一个线程内部都有自己的程序计数器,是相互独立的,保证每个线程的程序运行不会出错,因此程序计数器是线程私有的。

    在idea将Java代码运行时都会被转译成字节码文件,字节码文件是二进制文件,识别起来比较困难,所以在编译时用到计数器,为编译好的字节码添加行号,后期调用的时候就能按顺序分条执行。记录程序运行的位置。

    虚拟机栈:

    线程私有的,生命周期和线程相同,它描述的是Java方法执行的内存模型,每一个虚拟机栈都有自己的栈针,每一个方法的执行都是入栈和出栈的过程(想到关于栈和队列的区别,有一个形象的例子,队列是先进先出 吃了拉,栈是先进后出 吃了吐 ),每一个栈中都有着局部变量表和操作数栈,局部变量表是变量值的存储空间,用于存放方法参数和方法内部定义的局部变量,操作数栈存储的数据与局部变量表一致,是通过弹栈和压栈来进行访问的,操作数栈可以理解为Java虚拟机栈中的一个用于计算的临时数据存储区。(Java的基本数据类型大部分都是存储在栈的,除了一些引用变量和引用类型。String不是基本据类型!基本数据类型就只有八个,数值型:byte,short,int,long,浮点型:float,double,字符型:char,布尔型:boolean。

    方法区:

    也叫永久区,jdk8以后叫元数据区,是线程共享,里面存储着被虚拟机加载的类信息,常量,静态变量

    程序执行时,将字节码文件加载到方法区的常量池,存储一些和类有关的属性,方法区的清理也是通过垃圾回收,回收目标主要是常量池中废弃的常量和不再使用的类型。

     堆:

    堆区用于存放所有new出来的对象和数组,是线程共享的,堆区中的对象和栈区中的对象往往是成对出现的,一般的程序是通过栈区的对象引用来访问堆区的对象,因为是共享的,意味着对个对象引用可以指向同一个对象,在没有引用变量的指向时,就会变成垃圾,不被使用,被垃圾回收机制清理。

    看一下代码的执行结果。

     public static void main(String[] args) {
            ArrayList<String> a = null;
            test(a);
            System.out.println(a.size());
        }
    
        public static void test(ArrayList<String> a){
            a = new ArrayList<>();
            a.add("a");
        }

    执行后会返回什么?打印出1吗?

    结果显然不是,会在 System.out.println(a.size()); 时抛出空指针异常。

    我们分析下程序执行的内存模型。

    首先定义了一个ArrayList类型的a变量,a是一个指针,不过现在指向的是null。

    调用了test方法,传入形参a,实际上传的是a的副本。

    在静态方法test中,new了一个arrayList,在堆中开辟了空间存储了new的对象,将a指向堆中new出来对象的地址。

    然后执行 a.add("a"); 

    test方法结束,销毁test方法执行时产生的局部变量。

    回到main方法中,打印a.size时的a还是之前声明的指向null的变量。故抛出空指针异常。

    https://www.bilibili.com/video/BV12t411u726?from=search&seid=1631061805620865620

  • 相关阅读:
    Deep Learning 15:RBM的学习
    [解惑]MHA基本原理
    里程碑--学会蝶泳
    orchestrator中的raft snapshot操作
    使用binlog恢复被删除的数据
    关于MySQL binlog二进制日志
    无锁加载配置
    go tool trace 浏览器空白页问题 trace shows blank page
    godoc的使用
    Error 1390: Prepared statement contains too many placeholders
  • 原文地址:https://www.cnblogs.com/jxd283465/p/14634839.html
Copyright © 2011-2022 走看看