深入了解java虚拟机(JVM) 第四章 对象的创建
一、对象的创建过程
对象的创建过程大致可以分为六步,其中对象的分配尤为重要:

二、对象分配内存
一般来说对象分配内存有两种方式:
第一种是指针碰撞,这是一种比较理想的方式:如果Java堆是绝对规整的:一边是用过的内存,一边是空闲的内存,中间一个指针作为边界指示器;分配内存只需向空闲那边移动指针,这种分配方式称为"指针碰撞"(Bump the Pointer);
第二中方式是空闲列表,这中方式没有指针碰撞那么理想,但是也有他自身的优势:如果Java堆不是规整的:用过的和空闲的内存相互交错; 需要维护一个列表,记录哪些内存可用;分配内存时查表找到一个足够大的内存,并更新列表,这种分配方式称为"空闲列表"(Free List);
这两种方式各有各的优势,具体选用方式,需要根据垃圾收集器来进行选择,主要是根据垃圾回收器有无压缩来选择。
三、线程安全问题
在进行并发操作时,上面两种方式分配内存的操作都不是线程安全的,所以考虑到解决这种线程安全问题:
第一种:加锁,这种方式是开发过程中最容易使用的方式,也是最简单的方式,但是这种方式的缺点就是执行效率太低。
第二种:本地线程分配缓冲区(TLAB):把分配内存的动作按照线程划分在不同的空间中进行:在每个线程在Java堆预先分配一小块内存,称为本地线程分配缓冲区(Thread Local Allocation Buffer,TLAB);哪个线程需要分配内存就从哪个线程的TLAB上分配。
四、对象的结构
对象的结构分为三部分:
第一部分:Header(对象头),对象头又有两给部块组成
1.自身运行时数据(Mark word),这部分数据是对象主要存储的数据,主要有:
a.哈希值:这个值是通过一个native方法获取
b.GC分代年龄:这个是垃圾回收算法使用
以上介绍两种作用是太相同的,至于剩下的:c.锁状态标志、d.线程持有的锁、e.偏向线程ID、f.偏向时间戳都是作用于线程优化的
2.类型指针:对象指向类对象本身数据的指针
第二部分:实例数据(InstanceData):
实例数据部分是对象真正存储的有效信息,也既是我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的都需要记录下来。 这部分的存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)和字段在Java源码中定义顺序的影响。HotSpot虚拟机 默认的分配策略为longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers),从分配策略中可以看出,相同宽度的字段总是被分配到一起。在满足这个前提条件的情况下,在父类中定义的变量会出现在子类之前。如果 CompactFields参数值为true(默认为true),那子类之中较窄的变量也可能会插入到父类变量的空隙之中。
第三部分:对齐填充(Padding)
第三部分对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是对象的大小必须是8字节的整数倍。对象头正好是8字节的倍数(1倍或者2倍),因此当对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。
五、对象的访问定位
对立对象是为了使用对象.Java程序需要通过在栈上的reference数据操作堆上的具体对象. 由于reference类型在Java虚拟机规范中只规定了一个指向对象的引用,并没有定义这个引用应该通过何种方式去定位,访问堆中的对象的具体位置,所以对象的访问方式取决于虚拟机的实现而定的.。简单来说 栈指向堆中只会指向地址,至于地址存储的是否对象,我们是无法知道的,
解决这一问题目前有两种方式:
第一种:句柄指针:栈指向堆中的句柄池,句柄池中有实例对象的地址,通过句柄池指向对象
优点:栈地址永远不会改变,或者说引用地址不会改变
第二张:直接指针:reference中存储直接对象的地址,但是必须考虑放置访问类型数据的相关信息
优点:效率快,节省了一次指针定位的时间开销
深入了解java虚拟机(JVM) 第四章 对象的创建的更多相关文章
- [core java学习笔记][第四章对象与类]
4.3 用户自定义类 4.3.1 类数组的声明 需要两次new Employee[]=staff=new Employedd[3]; staff[0]=new Employedd(参数列表); sta ...
- 《深入理解Java虚拟机》(四)虚拟机性能监控与故障处理工具
虚拟机性能监控与故障处理工具 详解 4.1 概述 本文参考的是周志明的 <深入理解Java虚拟机> 第四章 ,为了整理思路,简单记录一下,方便后期查阅. JDK本身提供了很多方便的JVM性 ...
- [三] java虚拟机 JVM字节码 指令集 bytecode 操作码 指令分类用法 助记符
说明,本文的目的在于从宏观逻辑上介绍清楚绝大多数的字节码指令的含义以及分类 只要认真阅读本文必然能够对字节码指令集有所了解 如果需要了解清楚每一个指令的具体详尽用法,请参阅虚拟机规范 指令简介 计算机 ...
- Java虚拟机笔记(四):垃圾收集器
前言 前一篇文章介绍了内存的垃圾收集算法,现在介绍下内存回收的具体实现--垃圾收集器. 由于Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商,不同版本的虚拟机所提供的垃圾收集 ...
- 深入理解JAVA虚拟机JVM
深入理解JAVA虚拟机JVM Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.java之所以能实现一次编写到处执行,也就是因为jVM.原理:编 ...
- 《Java程序设计》第四章-认识对象
20145221<Java程序设计>第四章-认识对象 总结 教材学习内容总结 类与对象 定义:对象是Java语言中重要的组成部分,之前学过的C语言是面向过程的,而Java主要是面向对象的. ...
- 深入理解java虚拟机JVM(下)
深入理解java虚拟机JVM(下) 链接:https://pan.baidu.com/s/1c6pZjLeMQqc9t-OXvUM66w 提取码:uwak 复制这段内容后打开百度网盘手机App,操作更 ...
- Java虚拟机JVM学习07 类的卸载机制
Java虚拟机JVM学习07 类的卸载机制 类的生命周期 当Sample类被加载.连接和初始化后,它的生命周期就开始了. 当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就 ...
- Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...
随机推荐
- C#中使用OracleTransaction
1. OracleTransaction类的概述(from msdn ) 应用程序通过针对OracleConnection对象调用 BeginTransaction 来创建OracleT ...
- 使用jquery修改表单的提交地址
基本思路: 通过使用jquery选择器得到对应表单的jquery对象,然后使用attr方法修改对应的action 示例程序一: 默认情况下,该表单会提交到page_one.html 点击button之 ...
- photoshop最全快捷键列表
一.工具箱(多种工具共用一个快捷键的可同时按[Shift]加此快捷键选取) 矩形.椭圆选框工具 [M] 移动工具 [V] 套索.多边形套索.磁性套索 [L] 魔棒工具 [W] 裁剪工具 [C] 切片工 ...
- [C++] Pen questions & linux cmd
1.宏替换,完全展开替换,注意带来副作用 #include <stdio.h>#define 打印语句 printf(“hello”); Void main(void) { If (1) ...
- 出现命令提示apt-get -f install的解决方法
提示apt-get -f install这个信息,然后查看其他的提示信息发现时缺少了一些以依赖库. 解决办法为执行:sudo apt-get -f install命令. 该命令的含义是去补全那些缺少的 ...
- LWIP内存管理
LWIP是一种TCP/IP协议栈,与嵌入式操作系统一样也提供了内存管理. 内存池里面有多个同样大小的内存,不同类型的内存池其里面的内存大小不一样.
- C#序列化效率对比
原文出处:https://www.cnblogs.com/landeanfen/p/4627383.html 从使用序列化到现在,用到的无非下面几种方式:(1)JavaScriptSerializer ...
- mysql 事物ACID和隔离级别
⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则 ...
- SQL高性能分页
分页的场景就不多说了,无处不在. 方法一:利用row_number() with C as ( select ROW_NUMBER() over(order by orderdate,orderid) ...
- springboot+mongonDB
一.mongonDB基本介绍 什么是MongoDB ? MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. Mon ...