深入java虚拟机(二) 对象的创建
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虚拟机(二) 对象的创建的更多相关文章
- Java虚拟机(二)-对象创建
这一篇大致说明一下,对象在Java堆中对象分配.内存布局以及访问定位 1.对象的创建 虚拟机在遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引 ...
- JAVA虚拟机:对象的创建过程
简要说明的话,Java对象的创建过程分为下面几步: 1.执行相关检查: 2.为对象分配内存,将分配到的内存空间都初始化为零值: 3.进行构造代码块和构造函数的初始化 下面详细介绍这几个步骤: 1.执行 ...
- Java虚拟机学习-对象的创建
虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载.解析和初始化过.如果没有,必须先执行相应类的加载过程. 类加载 ...
- JAVA虚拟机:对象的创建
在虚拟机中,当遇到需要new一个对象时,虚拟机首先会去处于方法区的常量池中查找new指令的参数,即查找此类的符号引用是否已存在,并且检查此符号引用的代表类是否已经做过加载.解析和初始化,如果做过则不会 ...
- 深入Java虚拟机--判断对象存活状态
程序计数器,虚拟机栈和本地方法栈 首先我们先来看下垃圾回收中不会管理到的内存区域,在Java虚拟机的运行时数据区我们可以看到,程序计数器,虚拟机栈,本地方法栈这三个地方是比较特别的.这个三个部分的特点 ...
- JAVA虚拟机之对象探秘
上一章主要写到了JVM中运行时数据区域各个部分的功能及其作用.上一章说到了对象是分配在堆上面的,所以接下来我们写到对象在堆内存中是如何创建.如何布局.如何访问.1. 对象的创建 在java程序中对象的 ...
- 深入理解Java虚拟机(二)——HotSpot对象创建、内存、访问
对象的创建 虚拟机遇到一条字节码new指令时,开始对象创建过程. 首先去检查这个指令的参数是否能在常量池定位到一个类的符号引用: 检查这个符号引用代表的类是否已被加载.解析和初始化,如果没有就必须执行 ...
- 深入理解Java虚拟机(二)、Java对象的创建,内存布局和访问定位
对象的创建: Object obj = new Object(); 常量池中是否有Ljava.lang.Object
- Java 虚拟机的对象创建
堆中存储的内容:在程序运行时,动态创建的对象. 创建对象的四种方式:new,clone(浅复制),反射,反序列化. 浅复制:只能复制当前对象本身,如果当前对象(A)引用了另外的对象(B),则引用对象( ...
- Java虚拟机判定对象存活算法
1.引用计数算法 描述:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器值为0的对象就是不可能再被使用的. 特点:实现简单,判定效率高. ...
随机推荐
- PHP连接Azure Redis
概述 Azure Redis缓存基于流行的开源Redis缓存,可以通过各种Redis客户端进行访问,这些客户端适用于许多编程语言.每个客户端有自身的API,用于通过Redis命令调用Redis缓存实例 ...
- python selenium--常用函数3
ActionChains类鼠标操作的常用方法: 引入ActionChains类:from selenium.webdriver.common.action_chains import ActionCh ...
- LAMP架构二
安装PHP7 1.查看php配置文件信息(phpinfo),php有两个配置文件开发环境和生产环境 [root@localhost php-5.6.30]# /usr/local/php/bin/ph ...
- Springboot读取配置文件的两种方法
第一种: application.yml配置中的参数: zip: Hello Springboot 方法读取: @RestController public class ControllerTest ...
- vue的组件(先学习其他的ES6知识,之后再看这个) (未完)
https://blog.csdn.net/qq20004604/article/details/56965703
- Atitit.增强系统稳定性----虚拟内存的设置
Atitit.增强系统稳定性----虚拟内存的设置 1.1. 读取虚拟内存配置1 1.2. 禁止虚拟内存1 1.3. 默认所有驱动器虚拟内存1 1.4. 设置c d盘虚拟内存为系统管理1 1.5. 设 ...
- 2.请求库之requests
requests模块阅读目录: 介绍 基于GET请求 基于POST请求 响应Response 高级用法 一.介绍 #介绍:使用requests可以模拟浏览器的请求,比起之前用到的urllib,requ ...
- ubuntu MySQL数据库输入中文乱码 解决方案
一.登录MySQL查看用SHOW VARIABLES LIKE ‘character%’;下字符集,显示如下:+--------------------------+----------------- ...
- vim添加一键编译
引用来自: http://blog.chinaunix.net/uid-21202106-id-2406761.html; 事先声明,我使用的VIM完全是基于终端的,而不是gvim或vim-x11.因 ...
- mysql用事务插入数据
Connection conn = null; try { conn = queryRunner.getDataSource().getConnection(); ConnectionUtils.se ...