jvm详解-jvm内存区域

本文由larrylgq编写,转载请注明出处:http://blog.csdn.net/larrylgq/article/details/7395261

作者:吕桂强

邮箱:larry.lv.word@gmail.com


jvm中所有线程共享的数据区有方法区,堆。线程隔离的数据区有虚拟机栈,本地方法栈和程序计数器。

程序计数器

是用于当前线程执行字节码的行号指示器,是一块很小的内存空间,每个线程都有一个各线程计数器互不影响,独立存储。在工作时通过改变计数器的值来选取下一条需要执行的字节码指令,从而实现分支,循环,跳转,异常处理,线程恢复等基础功能,当执行Native方法时计数器的值为空。

java虚拟机栈

线程私有,生命周期与当前线程相同,线程中每个方法执行的时候会同时创建一个栈帧(stack frame)来存储局部变量表,操作数栈,动态连接,方法出口等信息,方法执行完成,该栈帧会在虚拟机栈中移除。

其中局部变量表存放了编译器可知的8中基本数据类型,对象引用,和returnAddress(指向一条字节码指令的地址)

注意:(与其它语言尾递归相比较)

1:当线程请求的栈深度大于虚拟机的最大允许深度会抛出StackOverflowError

2:如果虚拟机栈可以动态扩展,当扩展时申请不到足够的内存会抛出OutOfMemoryError

本地方法栈

和虚拟机栈相似,不过为虚拟机使用到的Native方法服务,(Sun HotSpot虚拟机直接将本地方法栈和虚拟机栈合在一起)

java堆

所有线程共享的一块内存区域,在虚拟机启动时创建,用于存放对象实例。java堆处于物理上不连续的内存空间,只需要在逻辑上是连续的即可,目前主流的虚拟机是按照扩展的方式实现(通过-Xmx和-Xms控制),当堆中没有内存进行实例分配且无法扩展时会抛出OutOfMemoryError

方法区

堆的逻辑部分,各个线程共享的内存区域,用于存储被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等,该区域的内存回收主要是常量池的回收和类型的卸载。当方法区无法内存分配时将跑出OutOfMemoryError

运行时常量池

用于存放class文件中的常量池(存放编译生成的字面量和符号引用http://blog.csdn.net/larrylgq/article/details/7240329),具有动态性,运行期间也可能将新的常量放入池中eg:String的intern()

直接内存:(Direct Memory)

 jdk1.4之后使用非直接缓冲区时会使用Native函数库直接分配堆外内存,然后通过java堆里的DirectByteBuffer对象作为这块内存的引用来进行操作,可以避免在java堆和Native堆中来回复制数据

对象存放

java中最简单的访问也要涉及java栈,堆,方法区3个最重要的内存区域,

eg:

方法体中出现下列代码Object obj = new Object();

其中Object obj作为一个reference类型数据存放在java栈的本地变量表中

new Object()部分则存放在堆中,存储Object类型的对象中所有实例字段数据的结构话内存

另外在堆中还需要查找到此对象类型,弗雷,实现接口,方法的地址信息,这些存放在方法区中

由于reference类型在jvm规范中只规定了指向对象的引用,没有定义定位的方式,因此一般虚拟机多采用句柄方式或者直接指针方式来定位

sun hot spot使用指针方式来定位即reference中直接存储的就是对象地址

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值