《JVM 系列》- Java内存模型

本文详细介绍了Java虚拟机(JVM)的内存结构,包括方法区、Java堆、Java虚拟机栈、PC寄存器、本地方法栈及运行时常量池等六个主要组成部分,并对各部分的功能进行了阐述。

一、内存划分

虚拟机规范中,将内存划分为六大部分,分别是方法区、JAVA堆、JAVA虚拟机栈、PC寄存器、本地方法栈以及运行时常量池。

其中运行时常量池是由方法区分配出来的一块区域。


 二、JAVA虚拟机规范与JAVA虚拟机

JAVA虚拟机规范是一种对JAVA虚拟机实现的规范要求,由oracle制定,而我们平时常说的JAVA虚拟机一般是指的一种具体的JAVA虚拟机规范的实现。

我们最经常使用的JAVA虚拟机是hotspot

三、结构图

程序要运行,在内存中就要有数据空间。在JVM中这块数据空间被称为运行时数据区。

150812_cqIT_2330610.png

另一张图

144730_vDM7_2330610.png

四、内存区域详解

方法区(全局共享)

方法区保存了运行时常量池、字段信息、方法信息、构造方法与普通函数的字节码内容以及一些特殊方法。

方法区主要重要的有三块:1.类的常量池;2.指向当前类Class类对象的引用;3.指向当前类ClassLoader类对象的引用

方法区与Java堆除了存储的信息不一样之外,这一部分Java虚拟机规范不强制要求实现自动内存管理系统(GC)。

Java堆(全局共享)

Java堆随着JAVA虚拟机的启动创建,储存着所有对象实例以及数组对象,而且内置了“自动内存管理系统”,也就是我们常说的垃圾搜集器(GC)。

对于JAVA虚拟机如何实现垃圾搜集器,JAVA虚拟机规范没有明确的规定,也正因如此,我们平时使用的JAVA虚拟机中提供了许多种垃圾搜集器,它们采用不同的算法以及实现方式,满足多方面的性能需求。

JAVA虚拟机栈(线程独有)

JAVA虚拟机栈是在创建线程的同时创建的,用于存储栈帧,JAVA虚拟机栈也是线程独有的。它的基本单位是栈帧。

栈帧

栈帧保存了局部变量表、操作数栈、程序计数器,以及对当前类的运行时常量池的引用。

栈帧是随着方法的调用而创建,随着方法的结束而销毁,如果方法抛出异常,也算方法结束。

它又肩负着处理方法返回值、动态链接以及异常分派的任务

局部变量表

是在编译时期就写入了class文件当中。

可以将它理解为一个对象数组,而里面按照索引0到length-1分别对应于每一个局部变量。

如果是实例方法的局部变量表,第0个局部变量会是一个指向当前实例的引用,也就是this关键字,其余的局部变量则从索引1开始。


操作数栈

它是一个后进先出(LIFO)栈,而它的长度也是在编译时期就写入了class文件当中,是固定的。它的作用就是提供字节码指令操作变量计算的空间,比如简单的,对于int a=9这句话来说,就需要先将9压入操作数栈,再将9赋给a这个变量。

PC寄存器(线程独有)

程序计数器(Program Counter Register),它记载着每一个线程当前运行的JAVA方法的地址,如果是当前执行的是本地方法,则程序计数器会是一个空地址(undefined)。

PC在每次指令执行后自增,维护下一个将要执行指令的地址。

在JVM模型中, 字节码解释器就是通过改变PC值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖PC完成。

本地方法栈(线程独有)

本地方法栈是一个传统的栈,它用来支持native方法的执行。

如果JAVA虚拟机是使用的其它语言实现指令集解释器的时候,也会用到本地方法栈。

如果前面这两种都未发生,也就是说如果JAVA虚拟机不依赖于本地方法栈,而且JAVA虚拟机也不支持native方法,则不需要本地方法栈。而如果需要的话,则本地方法栈也是随每一个线程的启动而创建的。

五、内存管理

内存管理分为内存分配和内存释放。大致分为两部分,一部分是全局共享,一部分是线程独有。

线程独有

对于线程独有的这部分内存,都是随着线程的启动而创建,而当线程被销毁时,内存也就随之释放。

这一部分内存,不需要垃圾搜集器的管理,而是JAVA虚拟机来主动管理,每当一个线程被创建的时候,JAVA虚拟机就会为其分配相应的PC寄存器和JAVA虚拟机栈,如果需要的话,还会有本地方法栈。相应的,当一个线程被销毁的时候,JAVA虚拟机也会将这个线程所占有的内存全部释放。

全局共享

全局共享的这部分内存(以下简称堆),内存分配主要是由程序员显示的使用new关键字来触发的,至于new出来的这部分内存在哪分配,如何分配,则是JAVA虚拟机来决定。而这部分内存的释放,则是由自动内存管理系统(以下简称GC)来管理的。

通常情况下,堆内存分配是要依赖于GC的策略与实现的,在分配的时候,就要考虑好到时候如何回收这部分内存。也是正因为如此,对于内存分配这一部分的讲解来说,我们必须得先了解内存是如何被回收的,才能更好的理解内存要怎么被分配。

 

参考资料

http://blog.youkuaiyun.com/zjf280441589/article/details/53437703

http://www.cnblogs.com/zuoxiaolong/p/jvm1.html

 

 

 

 

转载于:https://my.oschina.net/kimisme/blog/1593265

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值