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分代年龄等信息。这些信息都存放在对象的对象头中,至此,对于虚拟机来说,一个对象的创建过程就结束了。

转载于:https://www.cnblogs.com/bxljoy/p/7278948.html

深入java虚拟机(二) 对象的创建相关推荐

  1. 从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?

    转载自   从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的? 先回顾一下Java程序执行的过程: Java程序执行时,第一步系统创建虚拟机进程,然后虚拟器用类加载器Class Loade ...

  2. Java 面向对象与对象的创建过程及变量

    Java 面向对象与对象的创建过程及变量: 1.面向对象和面向过程的思想对比 : ​ 面向过程 :是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的 ​ 面向对象 :是一种以对象为中心的编 ...

  3. Java虚拟机:对象创建过程与类加载机制、双亲委派模型

    一.对象的创建过程: 1.对象的创建过程: 对象的创建过程一般是从 new 指令(JVM层面)开始的,整个创建过程如下: (1)首先检查 new 指令的参数是否能在常量池中定位到一个类的符号引用: ( ...

  4. java虚拟机(二)

    2019独角兽企业重金招聘Python工程师标准>>> 一.GC 1.垃圾回收器 垃圾收集 Garbage Collection 通常被称为"GC"; jvm 中 ...

  5. Java虚拟机专题对象内存定位

    一  对象在内存中的布局 1.1对象的创建过程 对象的创建过程可以如下图所示: 1.2 什么是符号引用和直接引用,为什么需要在常量池定位到符号的引号? 在类的解析阶段,把虚拟机常量池内的符号引号替换为 ...

  6. java中对象的生存期_深入理解Java虚拟机-判断对象是否存活算法与对象引用

    我们知道Java中的对象一般存放在堆中,但是总不能让这些对象一直占着内存空间,这些对象最终都会被回收并释放内存,那么我们如何判断对象已经成为垃圾呢?这篇文章会提出两种算法解决这个问题.另外,本文还要谈 ...

  7. java占位符填充_程序员:深入理解Java虚拟机,对象的内存布局

    在 HotSpot 虚拟机中,对象在内存中存储的布局分为 3 块区域:对象头 ( Header ) .实例数据 ( InstanceData ) 和对齐填充 (Padding) . 一.对象的内存布局 ...

  8. 深入理解Java虚拟机二(类加载器和类的加载过程)

    类加载器子系统作用 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识. ClassLoader只负责class文件的加载,至于它是否可以运行,则由Ex ...

  9. 手写java_手写JAVA虚拟机(二)——实现java命令行

    咱们都知道,咱们编译.java并运转.class文件时,需求一些java指令,如最简略的helloworld程序.java初学者可以看一下下面的教程. 这儿的程序最好不要加包名,因为加了包名的话编译和 ...

  10. Java虚拟机笔记-对象

    对象的创建:当虚拟机遇到一条new指令时,会去检查这个类是否已经被加载.解析.初始化过,如果没有,会执行类加载过程,当类加载检查通过之后会给对象分配内存,内存分配完成之后,虚拟机会对对象进行必要的设置 ...

最新文章

  1. Maya阿诺德室外环境灯光照明和渲染技术学习视频教程
  2. 如何使用阿里云服务器
  3. springboot 按钮权限验证_springboot学习之权限系统登录验证SpringSecurity
  4. React上下文-Context
  5. python命令行参数作用_Python命令行参数解析模块argparse
  6. 深度学习(02)-- ANN学习
  7. C#中的泛型化方法的实现
  8. 如何用MobaXterm查看日志信息以及xml
  9. 如何用Mac 自带的 Automator 进行图片格式转换?
  10. 批量快速截图方法(snipaste)
  11. 使用计算机模拟抛硬币,计算机模拟抛硬币实验学生任务单.pdf
  12. 未能连接到imap服务器,roundcube无法连接imap服务器登录
  13. Edge浏览器打不开网页解决方法教学
  14. JAVA时间字符串去空格、冒号和横杠
  15. 移动端产品设计(02)-移动APP产品结构
  16. FMRI及NMR简介
  17. 关于windows server 2016服务器 exchange 2010 managment Shell 停止工作的问题(已解决)
  18. C++:数组、链表与哈希表
  19. C#中三层架构UI、BLL、DAL、Model实际操作
  20. 为什么要清除浮动?清除浮动的方式?

热门文章

  1. C#方法的参数 Ref Out Params 4种类型的参数
  2. html span标签 不换行(有时span带中文时候是可以自动换行的)
  3. jsp网页上实现计算三角形面积小程序
  4. Linux内存管理(一)——从硬件角度看内存管理
  5. ipc java_java – Thrift有IPC传输实现吗?或低延迟SOA解决方案
  6. (66)UART接口波特率是多少?以及异步采样时钟是多少频率?
  7. VS Code调试C代码
  8. efcore 批量_EFcore使用EFCore.BulkExtensions 批量增加、删除、修改
  9. android 编译 oserror,编译android kernel时,关闭error, forbidden warning
  10. nginx的模块化体系结构