文档章节

java虚拟机学习(二)java对象的创建及访问定位

younchen
 younchen
发布于 2015/09/16 16:19
字数 1111
阅读 485
收藏 5

java对象的创建过程:

  1. 对象的创建开始

    虚拟机遇到new 关键字的时候,首先去常量池中寻找有没有这个类的符号引用,并且检查该引用的类是否已经被加载,解析,和初始化过,如果没有则会先执行该类的加载过程, 在通过检查后,虚拟机为该新生对象分配内存。

  2. 分配内存

    为对象分配内存有俩种方式: 

    一种分配方式是“指针碰撞",在内存规整的时候,已使用的内存在一侧,未使用的内存在一侧时,中间为指示器指针,这个时候的内存分配就是把指示器指针向未使用的区域移动至创建的对象大小相等的距离。

    另一种分配方式是“空闲列表”,当内存不规整时,虚拟机必须在不连续的内存空间寻找一块适合对象大小的内存区域,并使用一个列表去维护创建的每一个区域,并更新列表上的记录。

    选择那种分配方式是由堆内存是否规整决定,又由所采用的gc是否带有压缩整理功能决定。

    当面临并发时时,有可能存在,虚拟机给对象A分配内存时指针还未来得及改变,这个时候同时又有B对象使用指针来分配内存解决这个问题的两种式:

    一种是对分配内存空间的操作进行同步处理 ,虚拟机采用的CAS(见http://www.blogjava.net/xylz/archive/2010/07/04/325206.html) 和失败重试的方式保证更新操作的原子性,另一种是把内存分配的动作按照线程划分在不同的空间进行,即每一个线程都在java堆中预先分配一小块内存。又称本地线程分配缓冲(Thread Local Allocation Buffer,简称TLAB)。 TLAB用完时分配新的TLAB  时需要同步锁定操作。虚拟机设置使用TLAB,可以通过-XX:+/UseTLAB参数设定。

  3. 初始化对象内存空间

    内存分配完成之后,虚拟机对该对象分到的内存空间初始化为零值(除了对象头),如果使用了TLAB ,这一工作也可以提前至TLAB分配时进行。 初始化零值这一步也是为什么对象刚创建就可以使用的原因。

  4. 对象设置

    虚拟机对对象进行设置,比如对象是那个类的实例,对象的哈希值,gc分带年龄等,这些信息都存在对象的头之中。之后就是执行<init>方法,到此类创建结束。

java对象的内存布局

    对象在内存中分三块区域, 对象头,实例数据,对齐填充。

    java对象头部分俩个部分:一部分是用来存对象本身的运行时数据,比如:哈希code, gc分带年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳

    另一部分是类型的指针,指向类元数据,虚拟机通过这个指针确定它属于那个类的实例,查找对象的元数据信息,并不一定需要经过对象本身。

    实例数据部分是对象真正存储的有效信息,也是代码中所定义的类型的字段内容,无论是父类还是子类的都需要记录。

    对齐填充不是必然存在的,它只是起占位符的作用,HotSpot VM的自动内存管理系统要求对象的起始地址必须是8字节的整数倍,如果不是则需要通过对齐填充来补全。

对象的访问定位:

  一种是通过句柄访问,reference中存储的是句柄地址,这种方式首先需要在java堆中划分一块内存作为句柄池,这种方法的好处是,当对象指针发生改变比如:对象被移动,这个时候reference本身不需要改变。

    另一种是直接指针访问,reference直接指向java堆中的类对象地址。对象访问在java虚拟机中很频繁,所以第一种方法会造成一定的开销成本。

 

© 著作权归作者所有

共有 人打赏支持
younchen
粉丝 8
博文 94
码字总数 29970
作品 0
延吉
程序员
私信 提问
加载中

评论(1)

w
wliang777
对象的访问定位
两种机制,分别在什么时候会用到。
JVM学习之——Java内存区域

为了加深对Java语言的理解,加深对Java虚拟机工作机制、底层特性的了解和掌握,准备在闲暇时间,抽空对《深入理解Java虚拟机 JVM高级特性与最佳实践》一书进行学习。本文是学习此书第2章时的...

你想要怎样的未来
2018/05/27
0
0
Java虚拟机内存管理(二)—堆的使用

Java 与 C++ 之间有一堵由内存动态分配和垃圾收集技术所围成的 “高墙”,墙外面的人想进去,墙里面的人却想出来。——《深入理解Java虚拟机:JVM高级特性与最佳时实践(第二版)》周志明 Ja...

Wizey
2018/08/30
0
0
虚拟机学习之一:java内存区域与内存溢出异常

1.运行时数据区域 java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途和创建、销毁时间,有的区域伴随虚拟机进程的启动而存在,有些区...

贾峰uk
2018/10/21
0
0
对象的访问定位 - 句柄、指针

建立对象是为了使用对象,我们的Java程序需要通过栈上的reference数据来操作堆上的具体对象。由于reference 类型在Java虚拟机规范中只规定了一个指向对象的引用,并没有定义这个引用应该通过...

晨猫
2018/02/16
0
3
JVM学习系列之对象访问的两种方式句柄和直接指针

使用Java开发的人都清楚在Java中对象引用作用类似C++中指针,通过对象引用定位对象,但是具体在JVM中又是采用什么方式去定位堆中对象的具体位置,大部分人都不太了解,这里我们讲述下不同Jav...

老韭菜
2018/08/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day11

architect刘源源
今天
7
0
论学好Linux系统的超级重要性

不知道各位在日常的工作生活中有没有接触过“rm -rf /*”这个命令,因为这个命令搞出来的事情可还不少呢!前段时间就在一个群里看到了有个小伙子,老板让他去维护一下服务器,这小伙也不太懂...

Linux就该这么学
昨天
6
0
git 使用

1,首先在github配置好信息和仓库,然后在本地进行操作 git init git config user.name 'zhangwuer' git config user.email '56789053@qq.com' 2,与远程分支建立连接 git checkout -b test......

天王盖地虎626
昨天
3
0
git checkout 命令详解

在日常的git操作中,git checkout——检出,是我们的常用命令。最为常用的两种情形是创建分支和切换分支。 在下面的命令中,使用了一些简写,在这里说明一下: git st # git statusgit ci ...

shzwork
昨天
11
0
【Nginx】Nginx多级代理,获取客户端真实请求IP以及每级代理IP

Nginx多级代理,获取客户端真实请求IP以及每级代理IP 如图所示,每一级nginx里的location配置里需要加上对应的配置,最后一级nginx是直接到应用,测试时为了方便,直接用echo模块去测试,打印...

薛定谔的旺
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部