深入理解Java虚拟机笔记——java虚拟机内存区域和对象创建

java虚拟机内存区域图例如下:


根据图示可以知道,java虚拟机内存区域可以分为线程共享和独有两大部分,现就各模块介绍如下:

java堆

        该区域为所有线程共享,也是最大的一块内存区域,通常也是GC(垃圾回收)区域,因此也被成为“GC堆”。该区域主要存储对象实例以及数组实例。为对象划分内存通常有两种方法:指针碰撞和采用空闲列表,具体采用哪种取决于垃圾收集器是否带有压缩整理功能。另外还要考虑线程安全性,比如同时申请了两个对象内存时要避免冲突。解决这个问题有两个方案,一种是对分配内存空间的动作进行同步处理;另一种是给每个线程预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer ,TLAB)。当分配对象内存时,先使用自己的TLAB,当用完的时候才需要同步锁定去分配新的内存。

方法区

       方法区(有些人称为“永久代”)主要存储被虚拟机加载的类信息、常量、静态变量、以及编译后的代码等数据。另外需要注意的是“运行时常量池”也在其中。Class文件中除了有类的版本、字段、方法、接口外,还有一项信息是常量池,用于存储编译器生成的各种字面值和符号引用,这类数据当类被加载时存入“运行时常量池”。运行时常量池具有动态性,也就是程序运行期间依然可以进入常量池。

            这里补充一点String类的intern方法的介绍:参见http://www.cnblogs.com/wanlipeng/archive/2010/10/21/1857513.html

虚拟机栈

        此区域属于单个线程独有,他描述了java方法的运行模型。每个方法运行前都会创建一个栈帧(statck frame),栈帧包括局部变量表(存储方法参数及方法类定义的变量。第一个Slot(最小单位)存所属对象实例,即this)、动态链接(部分符号引用在类加载阶段或者第一次使用的时候就转化为直接引用,这种转化称为静态解析。另外一部分将在第一次运行期间转化为直接引用,成为动态链接)、方法出口、操作数栈(计算过程中存储中间结果)等信息。每个方法的执行和结束就对应一个栈帧在虚拟机栈中进入和弹出的过程。

         局部变量表信息存放了编译期就可知的基本数据类型、对象引用(reference类型,可能是一个指向对象的指针或者句柄)和一个returnAddress类型(指向了一条字节码指令的地址)。其中long/double类型是64位,占2个局部变量空间。局部变量表在编译期就确定,方法执行期间不会改变大小。

此处添加引用的介绍:参见http://blog.sina.com.cn/s/blog_4cd5d2bb0100ve9r.html

本地方法栈

跟虚拟机栈类似,只不过它对应于虚拟机执行本地方法(native方法,可以是用c/c++等其他语法编写)。

程序计数器

当线程执行java方法时,程序计数器记录正在执行的虚拟机字节码指令的地址。若线程执行native方法,该值为空(undefined)。

直接内存
直接内存并不是java虚拟机运行时数据区的一部分。在jdk1.4引入了NIO类,引入了一种基于通道和缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存。

下面介绍下对象(不包括数组和Class对象)的创建过程:
      当虚拟机遇到一个new语句时,首先检查常量池是否有该类的符号引用,并检查是否加载、解析、和初始化过,如果没有将加载该类。然后在java堆区域分配内存(该内存在java类加载时确定,不包括数组)。对象的内存布局包括三部分:对象头、实例数据、对齐填充。
对象头分为两部分:一是存储对象自身的运行时数据,比如hash码、GC分代年龄、锁状态等信息。另一部分是类元数据指针,以确定该对象所属的类。
实例数据:该对象真正存储的有效信息,包括代码中定义的字段等信息。
对齐填充:因为jvm要求8字节对齐,所以没有对齐时用该区域填充。

对象的访问定位:
      本地java栈上的引用(reference数据)存储一个指向对象的指针或者句柄。前者即Sun HotSpot虚拟机采用的方式,优先是速度快。后者是在java堆去建立一个句柄池,由句柄指向对象,这种方式优点是当对象位置变化时只需要改变句柄即可(由于GC原因,对象移动比较频繁)。
       关于成员变量、静态变量、局部变量的存储位置参见http://blog.csdn.net/haovip123/article/details/43883109


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值