JVM笔记----Java虚拟机内部结构介绍

  Java与c++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外的人想进去,墙里面的人却想出来。

                                 —— 《深入理解Java虚拟机》 周志明

 

  对于c++来说 , 在内存管理领域,他们既是拥有最高权利的皇帝,又是从事最基础工作的劳动人民。他们拥有每一个对象的

所有权,又背负着维护每一个对象的责任。

  而对于Java程序员来说,在JVM的帮助下,不再需要为每一个new 操作去写配对的delete / free 代码,不容易出现内存泄漏

和内存溢出的问题。

  那么就然我们来一探JVM的底层结构吧~

 

          

 

上图就是JVM的结构啦~ 那么下面就让我来 一 一 介绍 每块区域的职责和特点

  

  

  当我们把java程序写出来的时候,首先要对它进行编译才可以运行,比如上图的Math类,我们要首先用javac指令

把它编译生成字节码文件( .class ) , 然后就可以运行了,而运行时的内存管理就依赖于JVM,由JVM对我们的内存

进行管理。

 

  程序计数器:

   

        想必学过计算机组成原理的同学对程序计数器都不陌生吧~ 它负责记录我们的代码运行到哪一行,以及负责一些流程控制。

  

  字节码解释器工作时会通过改变计数器的值来选去下一条指令,分支,循环,跳转,异常处理,线程恢复都需要计数器。

  

  每条线程都需要一个独立计数器,各线程计数器互不影响,这类内存区域称为“线程私有”内存。

 

  栈(线程):

  

 线程私有,生命周期与线程相同。

 

  每个方法在执行的时候会创建一个栈帧 用于存储  局部变量表 、 操作数栈 、 动态链接 、 方法出口

     

    每一个方法从调用直到执行完成的过程,就对应一个栈帧在虚拟机中入栈到出栈的过程。

  

  局部变量表: 存放各种基本数据类型 ( boolean , byte , char , short , int , float , long , double ) 没有 String!

        对象引用 ( 指向对象起始地址的指针 )

        return Address 类型 (指向一条字节码指令的地址)

        

      它有哪些异常呢? 有:线程请求的栈深度大于JVM所允许,StackOverflowError

                若栈可以动态扩展,无发申请到足够内存时,OutOfMemoryError

   

   本地方法栈: 

      与虚拟机栈区别:虚拟机栈为JVM执行Java方法服务

              方法栈为JVM使用到的Native方法服务

        

      也会抛出StackOverflowError, OutOfMemoryError

 堆:

      内存最大 被所有线程共享 

    几乎所有的对象实例和数组都要在堆中分配内存(除了静态等)

    若在堆中没有内存完成实例分配,且堆无法扩展时,抛出OutOfMemoryError

  方法区:

   线程共享

    

    用于存储类信息,常量,静态变量,编译后的代码

    

    垃圾收集很少出现

  

  运行时常量池:

     方法区的一部分

    存放编译期生成的各种字面量和符号引号(常量池)

    这部分内容在类加载后进入方法区的运行时常量池中存放

 

 直接内存:

     不是JVM运行时数据区的一部分,也不是JVM规范中定义的内存区域

 

那么今天的JVM就介绍到这里~

下一次我会介绍JVM是如何创建对象的哦~

  

    

 

    

 

 

                         

posted @ 2021-08-20 14:45  Apak陈柏宇  阅读(157)  评论(0编辑  收藏  举报