java创建对象通常的方式是使用new指令,虚拟机会首先检查new指令的参数(也就是new关键字后面跟着的类名)是否能够在常量池中找到一个类的符号引用,并根据这个符号引用检查其代表的类是否已经加载、解析和初始化,如果没有就先执行类的加载过程。类加载检查后,就会给对象分配内存。新生的对象一般会存在于java堆中,根据java堆的情况,分配内存主要分为两种方式:“指针碰撞”(bump the pointer)和“空闲列表”(free list)。

指针碰撞:假设java堆内存是规整排列的,用过的内存放在一边,空闲的内存放在另一边,中间放着一个指针作为分界指示器,那分配内存操作只是将这个指针往空闲空间那边挪动一段与对象大小相同的距离。

空闲列表:假设java对内存是不规整排列的,虚拟机就需要维护一张空闲内存空间的地址列表,当给对象分配内存时,需要从空闲列表中找到足够的空闲内存空间划分给对象,并且在分配完毕后,还要更新这个空闲地址列表。

选用哪种分配方式取决于java堆内存是否规整,而堆内存是否规整又由虚拟机所采用的垃圾收集器是否带有压缩整理功能所决定。因此, 在使用Serial、ParNew等带有Compact过程的收集器时,系统采用的是指针碰撞,而使用CMS这种基于Mark-Sweep算法的收集器时,系统采用的是空闲列表。

对于创建对象这种频繁操作,虚拟机在分配内存时需要考虑修改指针位置的线程安全问题。解决方案有两种:一种是对分配内存空间的动作进行同步处理——虚拟机采用CAS配上失败重试的方式保证更新操作的原子性;另一种是把内存分配的动作按照线程分配在不同的空间中进行,即每个线程在内存中预先分配一小块内存,成为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB)。哪个线程分配内存,就在哪个线程的TLAB上分配,只有当TLAB用完并分配新的TLAB时,才需要同步锁定。

内存分配完成后,虚拟机将分配的内存空间都初始化为零值(不包括对象头),如果使用TLAB进行分配,则初始化可以提前至TLAB分配时进行。

最后,虚拟机对对象进行必要的设置,包括类的元数据、对象的哈希码、对象的GC分代年龄等信息。这些信息都存放在对象的对象头中,至此,对于虚拟机来说,一个对象的创建过程就结束了。

深入java虚拟机(二) 对象的创建的更多相关文章

  1. Java虚拟机(二)-对象创建

    这一篇大致说明一下,对象在Java堆中对象分配.内存布局以及访问定位 1.对象的创建 虚拟机在遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引 ...

  2. JAVA虚拟机:对象的创建过程

    简要说明的话,Java对象的创建过程分为下面几步: 1.执行相关检查: 2.为对象分配内存,将分配到的内存空间都初始化为零值: 3.进行构造代码块和构造函数的初始化 下面详细介绍这几个步骤: 1.执行 ...

  3. Java虚拟机学习-对象的创建

    虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载.解析和初始化过.如果没有,必须先执行相应类的加载过程. 类加载 ...

  4. JAVA虚拟机:对象的创建

    在虚拟机中,当遇到需要new一个对象时,虚拟机首先会去处于方法区的常量池中查找new指令的参数,即查找此类的符号引用是否已存在,并且检查此符号引用的代表类是否已经做过加载.解析和初始化,如果做过则不会 ...

  5. 深入Java虚拟机--判断对象存活状态

    程序计数器,虚拟机栈和本地方法栈 首先我们先来看下垃圾回收中不会管理到的内存区域,在Java虚拟机的运行时数据区我们可以看到,程序计数器,虚拟机栈,本地方法栈这三个地方是比较特别的.这个三个部分的特点 ...

  6. JAVA虚拟机之对象探秘

    上一章主要写到了JVM中运行时数据区域各个部分的功能及其作用.上一章说到了对象是分配在堆上面的,所以接下来我们写到对象在堆内存中是如何创建.如何布局.如何访问.1. 对象的创建 在java程序中对象的 ...

  7. 深入理解Java虚拟机(二)——HotSpot对象创建、内存、访问

    对象的创建 虚拟机遇到一条字节码new指令时,开始对象创建过程. 首先去检查这个指令的参数是否能在常量池定位到一个类的符号引用: 检查这个符号引用代表的类是否已被加载.解析和初始化,如果没有就必须执行 ...

  8. 深入理解Java虚拟机(二)、Java对象的创建,内存布局和访问定位

    对象的创建: Object obj = new Object(); 常量池中是否有Ljava.lang.Object

  9. Java 虚拟机的对象创建

    堆中存储的内容:在程序运行时,动态创建的对象. 创建对象的四种方式:new,clone(浅复制),反射,反序列化. 浅复制:只能复制当前对象本身,如果当前对象(A)引用了另外的对象(B),则引用对象( ...

  10. Java虚拟机判定对象存活算法

    1.引用计数算法 描述:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器值为0的对象就是不可能再被使用的. 特点:实现简单,判定效率高. ...

随机推荐

  1. X86服务器、小型机、大型机、塔式、机架式、刀片式服务器、工作站

    ü  服务器分:x86(PC)服务器,小型机(Unix服务器),大型机: pc服务器则主要指基于intel处理器的x86架构,是一个通用开放的系统. UNIX服务器,也就是中国业内习惯上说的小型机,在 ...

  2. JS遍历数组类型元素

    已停供用户不能再次停供,之前没太处理过多维数组的遍历,趁这个机会回顾一下js数组遍历 可以看出rows 获取了两条数据,为二维数组类型 方法 function batchTgWin() { var r ...

  3. java的日期格式使用

    转自:  关于java中六个时间类的使用和区别     java.util.Date java.sql.Date  java.sql.Time  java.sql.Timestamp java.tex ...

  4. bootstrap学习笔记 多媒体对象

    本文将介绍Bootstrap中的多媒体对象(Media Object).这些抽象的对象样式用于创建各种类型的组件(比如博客评论),我们可以在组件中使用图文混排,图像可以左对齐或者右对齐.媒体对象可以用 ...

  5. centos(7.0) 上 crontab 计划任务

    yum install vixie-cron yum install crontabs /bin/systemctl restart crond.service  #启动服务 /bin/systemc ...

  6. django学习笔记【004】创建带有model的app

    第一步:配置连接字符串 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'tempdb', 'HOST ...

  7. 可能是最通俗易懂的 Java 位操作运算讲解

    https://blog.csdn.net/briblue/article/details/70296326

  8. 608. Two Sum - Input array is sorted【medium】

    Given an array of integers that is already sorted in ascending order, find two numbers such that the ...

  9. 关于引脚复用,不得不提的GPIO_Pin_sources 和GPIO_Pin

    今天在端口复用时遇到了困惑,参考:http://www.51hei.com/bbs/dpj-40992-1.html 调整前的代码GPIO_PinAFConfig(GPIOA,GPIO_Pin_9,G ...

  10. session用户账号认证(一个用户登陆,踢出前一个用户)

    在web.xml中配置: <listener> <listener-class>cn.edu.hbcf.common.listener.SessionAttributeList ...