jvm运行时内存划分

Posted 迷路的小朋友

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jvm运行时内存划分相关的知识,希望对你有一定的参考价值。

(根据《深入理解java虚拟机》这本书总结)   

本文主要解释jvm内存模型,以及各个部分的作用。都是自己总结的给自己看的通俗语言,未用专业术语的见谅。 

 一、为什么要了解jvm内存模型?

  在了解一个类的编译-加载-内存分配-初始化所有过程前,要先了解jvm的内存模型。这样对整个java体系可能会更加便于理解。当然,如果不理解这些,也是没关系的,照样可以进行java开发。

   二、jvm内存模型

  1、根据自己的理解举个最简单的例子,一个main方法启动,进程运行,在这个过程中,会调用方法、开启多个线程、有局部变量、成员变量、静态变量、有基本对象、有引用对象、可能还包含锁等概念。这些内容在jvm虚拟机中是怎么存储的呢?下面就是jvm运行时的最简单的内存划分介绍。

  2、jvm运行时,内存主要有五个部分,具体的作用及划分如下:

    按线程是否共享划分:

    线程共享的区域有

     (1)堆内存:堆内存最大的作用是存储对象实例,通俗的理解,当我们new一个对象的时候,引用所指向的内容就存在堆中,也存储类基本类型成员变量。

     (2)方法区:当类编译阶段,将编译的字节码文件、类信息、静态变量,并且常量池也在方法区中(常量池)。

    线程私有的区域有:

     (3)栈内存:栈的生命周期跟线程的生命周期是一样的,当调用一个方法的时候,就会有一个方法入栈,虚拟机会为这个方法创建一个栈帧,栈帧中存储着局                                      部变量表等信息(局部变量的大小在类加载的时候就能确定,所以栈帧中局部便量表占用的大小是固定的),另外栈中存储着局部基本类型变                                        量、类涉及的所有对象的引用(可能指向堆也可能指向方法去)

     (4)本地方法栈:本地方法栈和栈相似,区别是本地方法栈是用来执行类需要的native方法的。

     (5)程序计数器:当前线程所执行的字节码行号指示器。

  3、根据一个类总结相关的存储位置:

    类信息、方法等字节码:方法区

    基本类型成员变量:堆(易混)

    引用类型成员变量:堆

    引用类型成员变量引用地址:栈

    基本类型局部变量:栈

    引用类型局部变量:堆

    引用类型局部变量引用地址:栈

    基本数据类型静态变量:方法区

    引用数据类型静态变量:方法区

  三、new对象的整个过程(针对hotspot虚拟机)

   当调用new方法时,对于程序语言,只是一行代码,一个对象实例就产生了,但是对于虚拟机来说,过程如下:

    1、检查new的类在方法区中的类信息是否存在,如果存在,检查该类是否被虚拟机加载过,如果没有加载过,需要先加载类信息

    2、进行内存分配,在堆中对实例对象进行内存地址分配。

    3、将实例分配到的内存空间初始化为零值。

    4、对实例进行必要的信息设置,如实例的哈西值、实例数据哪个类new出来的等

   上面的四部对于虚拟机来说,对象实例就是创建好了。程序语言则需要对类继续进行初始化,比如有些对象有显式初始值等等

    

  

以上是关于jvm运行时内存划分的主要内容,如果未能解决你的问题,请参考以下文章

Java运行时环境---内存划分

JVM运行时数据区划分

JVM内存区域划分

深入理解java:1.3.1 JVM内存区域的划分(运行时数据区)

JVM内存区域划分

JVM运行时的内存划分--JDK1.8