JVM的内存空间

一、JVM运行起来,就会给内存划分空间,这块空间成为运行时数据区。运行时数据区主要划分为以下几部分内容:

  1.栈

    每一个线程运行起来的都会对应一个栈(线程栈),栈中的数据是该线程独有的,不会产生资源共享的情况,因此栈是线程安全的

    栈当中存放的是栈帧,当线程调用方法时,就形成一个栈帧,并将这个栈帧进行压栈操作,方法执行完之后进行出栈操作。

    这个栈帧中包括:局部变量、操作数栈、指向当前方法对应类的常量池引用、方法返回地址等信息

  2.本地方法栈

    本地方法栈的机制和栈相似,区别在于:栈运行的是java方法,而本地方法栈中运行的是本地方法

    本地方法是指JVM需要调用非Java语言所实现的方法,

    例如C语言。在JVM规范中,没有强化性要求实现方一定要划分出本地方法栈(例如:HotSpot虚拟机将本地方法栈和栈合二为一)和具体实现(不同的操作系统,对JVM

    规范的具体实现都不一样)。

  3.程序计数器

    程序计数器也可以成为PC寄存器,通俗的讲就是指令缓存,它主要用来缓存当前程序执行的下一条指令的地址,CPU根据这个地址找到将要执行的指令。这个寄存器是JVM

内部实现的,不是物理概念上的计数器,不过和JVM的实现逻辑一样。

  4.堆

    堆内存主要存放创建的对象和数组,堆内存在JVM中是唯一的,被所有的线程说共享。堆里面每一个对象都存放实例的实例变量,堆内存中的对象没有被引用,会自动被java的垃圾回收机制回收。

    当在方法中定义了局部变量,如果变量是基本数据类型,直接存放在栈内存中,如果这个变量是引用数据类型,会将变量值存放在堆内存中,栈内存中只存放引用地址。

  5.方法区

    方法区在JVM中也是非常重要的一块内存区域,和堆一样,方法区可以被多个线程共享。主要存放每一个被加载的class的信息

    扩展:每一个被加载的class信息有哪些东西呢?

      class信息主要包含魔数(确定是否是一个class文件),常量池,访问标志(当前的类是普通类还是接口,是否是抽象类,是否被public修饰,是否使用了final修饰等描述信息......),字段表集合信息(使用什么访问修饰符,是实例变量还是静态变量,是否使用了final修饰等描述信息.....),方法表集合信息(使用什么访问修饰符,是否静态方法,是否使用了final修饰,是否使用了synchronized修饰,是否是native方法......)等内容。

    当一个类加载器加载了一个类的时候,会根据这个class文件创建一个class对象,class对象就包含了上述的信息。后续要创建这个类的实例,都根据这个class对象创建出来的。

  6.常量池

    常量池是方法区的一部分。存放class中最重要的资源,JVM为每一个class对象都维护者一个常量池

 

 

posted @ 2019-11-24 09:45  Runtimeing  阅读(744)  评论(0编辑  收藏  举报