一、JVM内存1(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出来的等
上面的四部对于虚拟机来说,对象实例就是创建好了。程序语言则需要对类继续进行初始化,比如有些对象有显式初始值等等