深入理解 Java 对象的内存布局】的更多相关文章

对于 Java 虚拟机,我们都知道其内存区域划分成:堆.方法区.虚拟机栈等区域.但一个对象在 Java 虚拟机中是怎样存储的,相信很少人会比较清楚地了解.Java 对象在 JVM 中的内存布局,是我们了解并发编程同步机制的基础. 在 HotSpot 虚拟机中,对象在内存中存储的布局可以分为 3 块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 对象头 HotSpot 虚拟机的对象头包括两部分信息,第一部分用于存储自身运行时的数据,第二部分用于存…
对象的内存布局 平时用java编写程序,你了解java对象的内存布局么? 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域: 对象头 实例数据 对齐填充 对象头 对象头包括两部分信息: MarkWord 第一部分用于存储对象 自身 的 运行时数据 ,如: 哈希码(HashCode) GC分代年龄 锁状态标志 线程持有的锁 偏向线程ID 偏向时间戳 这部分数据的长度在32和64位虚拟机中分别为32bit和64bit,官方的名称是 "MarkWord". Mark Word…
一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit)存储对象自身的运行时数据,包括哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时 间戳等   类型指针 即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.但是并不是所有类型虚拟机实现都必须在对象数据上保留类型指针,如果对象是一个java数组,那在对象头中还必…
先来看看Java对象在内存中的布局   一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit)存储对象自身的运行时数据,包括哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时 间戳等   类型指针 即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.但是并不是所有类型虚拟机实现都必须在对象数据上保留类型指针,如果…
1. 内存布局 在HotSpot虚拟机中,对象的内存布局可以分为三部分:对象头(Header). 实例数据(Instance Data)和对齐填充(Padding). 1) 对象头(Header): 对象头又可以分为两部分: 第一部分用来存储对象自身的运行时基本数据信息.如哈希码.GC分代年龄.锁状态标示.线程持有的锁等.这部分数据的长度在32bit和64bit虚拟机上分别为32bit和64bit.官方称呼是"Mark Word". 第二部分是类型指针,或者说指向类的元数据信息的引用.…
前一段时间再次拜读<Inside the C++ Object Model> 深入探索C++对象模型,有了进一步的理解,因此我也写了四篇博文算是读书笔记: Program Transformation Semantics (程序转换语义学) The Semantics of Copy Constructors(拷贝构造函数之编译背后的行为) The Semantics of Constructors: The Default Constructor (默认构造函数什么时候会被创建出来) The…
在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我们还可以通过反射机制.Object.clone 方法.反序列化以及 Unsafe.allocateInstance 方法来新建对象. 其中,Object.clone 方法和反序列化通过直接复制已有的数据,来初始化新建对象的实例字段.Unsafe.allocateInstance 方法则没有初始化实例字段,而 new 语句和反射机制,则是通过调用构造器来初始化实例字段. 以 new 语句为例,它编译而成的字节码将…
Java 创建对象的方式 1:new 语句和反射机制创建.该方式会调用类的构造器,同时满足诸多约束.如果一个类没有构造器的话,Java 编译器会自动添加一个无参数的构造器.子类的构造器需要调用父类的构造器,如果父类存在无参数构造器的话,该调用可以是隐式的.如果父类没有无参数构造器,那么子类的构造器则需要显式的调用父类带参数的构造器. 显式调用又可以分为两种,一种是使用"super"关键字调用父类构造器,二是用"this"关键字调用同一个类中的其他构造器.无论是直接或…
1.对象的创建过程 class loading class linking(verification,preparation,resolution) class initializing 申请对象内存 给对象的成员变量赋默认值 调用构造方法 成员变量顺序赋初始值 执行构造方法语句(如果有父类,则先调用父类的构造方法) 2.对象在内存中的存储布局 由于对象在内存中分配非常的依赖环境配置,所以先看下虚拟机的配置 1.观察虚拟机的配置 java -XX:+PrintCommandLineFlags -…
在上一篇文章中.我们列出了计算java对象大小的几个结论以及jol工具的使用,jol工具的源代码有兴趣的能够去看下.如今我们利用JDK中的sun.misc.Unsafe来计算下字段的偏移地址,一则验证下之前文章中的结论,再则跟jol输出结果对照下.怎样获取sun.misc.Unsafe对象.能够參考这篇文章. public class VO { public int a = 0; public long b = 0; public static String c= "123"; pub…
前言 大家好,又见面了,今天是JVM专题的第二篇文章,在上一篇文章中我们说了Java的类和对象在JVM中的存储方式,并使用HSDB进行佐证,没有看过上一篇文章的小伙伴可以点这里:<类和对象在JVM中是如何存储的,竟然有一半人回答不上来!> 这篇文章主要会对Java对象进行详细分析,基于上一篇文章,对Java对象的布局及其底层的一些机制进行解读,相信这些会对后期JVM调优有很大的帮助. 对象的内存布局 在上篇文章中我们提到,对象在JVM中是由一个Oop进行描述的.回顾一下,Oop由对象头(_ma…
一.先上答案 这个问题有坑,有两种回答 第一种解释: object实例对象,占16个字节. 第二种解释: Object o:普通对象指针(ordinary object pointer),占4个字节. new Object():object实例对象,占16个字节. 所以一共占:4+16=20个字节. 第二种解释就是在玩文字游戏了,但还是要知道的. 二.这个答案适用于所有情况吗 并不是,这个答案只适用于现在一般默认情况. 准确的说,只适用于Hotspot实现的64位虚拟机,默认开启了压缩类指针和压…
这里以HotSpot为例,且所说的对象指普通的Java对象,不包括数组和Class对象等. 1.对象创建的过程 1.类加载.解析.初始化:虚拟机遇到new时先检查此指令的参数是否能在常量池中找到类的符号引用,并检查符号引用代表的类是否被加载.解析.初始化,若没有则先进行类加载. 2.对象内存分配:类加载检查通过后,虚拟机为新生对象分配内存,对象所需内存大小在类加载完成后便可完全确定.分配内存的任务等同于从堆中分出一块确定大小的内存.(具体分配策略见:JVM内存分配策略-MarchOn) 根据内存…
对象的内存布局   在HotSpot虚拟机中,对象在内存中的存储布局可以划分为三个区域:对象头,实例数据,对齐填充.   对象头包括两部分信息:第一部分用于存储对象自身的运行时数据,如哈希码,GC分代年龄,锁状态标志等.对象头的另一部分是类型指针,即对象指向向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.   实例数据部分是对象真正存储的有效信息,也是代码中所定义的各种类型字段的内容.   对齐填充并不是一定存在的,它仅仅起着占位符的作用,这是由于HotSpot VM规定对…
一 对象的内存布局: 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header),实例数据(Instance Data)和对齐填充(Padding). HotSpot的对象头包括两部分信息,一部分存储对象运转时自身信息,例如hashCode,GC分代年龄,锁状态标志,线程持有的锁,偏向线程id,偏向时间戳等,这部分数据的长度在32和64位虚拟机中分别为32和64位,官方称之为“Mark World”.对象在运行时产生的数据很多,其实早已经超出了32或64位BitMa…
1. 对象的创建和分配 创建对象(如克隆.反序列化)通常仅仅一个new关键字,但在虚拟机中,对象的创建的过程需要如下步骤: 类加载检查 先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载.解析.初始化过,若没有,则必须先执行相应的类加载过程. 为新生对象分配内存 对象所需内存大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来.根据java堆内存是否绝对规整,划分方法不同: 1)指针碰撞(Bump…
概述 一个对象本身的内在结构需要一种描述方式,这个描述信息是以字节码的方法存储在方法区中的.Class本身就是一个对象,都以KB为单位,如果new Integer()为了表示一个数据就占用KB级别的内存就有点不值了,下面讲解JVM是如何做的.为了表示对象的属性.方法等信息,不得不需要结构描述.Hotspot VM使用对象头部的一个指针指向Class区域的方式来找到对象的Class描述,以及内部的方法.属性入口.如下图所示: 在HotSpot虚拟机中,对象在内存中存储布局分为2块区域:对象头(He…
简述 今天继续写<深入理解java虚拟机>的对象创建的理解.这次和上次隔的时间有些长,是因为有些东西确实不好理解,就查阅各种资料,然后弄明白了才来做记录. (此文中所阐述的内容都是以HotSpot虚拟机为例的.) 对象的创建 java程序在运行过程中无时无刻都有对象被创建出来,那么创建对象是个怎么样的过程呢?还是看看我自己的理解吧. 判断是否已经执行类加载 当虚拟机遇到一条new指令时 ,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载…
C++对象的内存布局以及虚函数表和虚基表 本文为整理文章, 参考: http://blog.csdn.net/haoel/article/details/3081328 http://blog.csdn.net/angelxf/article/details/7746034 整理的也不到位,还有很多不理解,先记下来. 遇到了一个面试题,是求对象所占空间的大小了.于是想了解一下C++中对象内存的布局. 先来一些结论,以便应付面试: l  空类.单一继承的空类.多重继承的空类所占空间大小为:1(字节…
HotSpot采用了OOP-Klass模型来描述Java类和对象.OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象的具体类型.为了更好理解这个模型,首先要介绍一下C++的内存对象模型和虚函数. 1.C++类对象的内存布局 我们使用Visual Studio工具来查看C++对象的内存布局,所以需要在当前项目上右键单击选择"属性"后,打开属性页,在配置属性->C/C++->命令行下的其它选项文本框中配置如下命令: /d1 re…
一.概述 我们在进行 Java 开发的时候,很少关心 Java 的内存分配等等,因为这些活都让 JVM 给我们做了.不仅自动给我们分配内存,还有自动的回收无需再占用的内存空间,以腾出内存供其他人使用.但是我们经常面临的一个问题就是内存泄漏,JVM无法完成回收工作,导致内存占用暴涨,最后可能让程序奔溃.本章主要了解下运行时数据区域分布情况以及溢出异常. 二.运行时数据区域 1.程序计数器 线程私有 当前线程所执行的字节码的行号指示器 Java 多线程是通过再一个内核中轮流执行实现的,计数器就保证了…
原文地址:http://rainforc.iteye.com/blog/2039501   1.实现线程的三种方式:   使用内核线程实现     内核线程(Kernel Thread, KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器对线程进行调度,并负责将线程的任务映射到各个处理器上.程序一般不会直接去使用内核线程,而是去使用内核线程的一种高级接口——轻量级进程(Light Weight Process,LWP),轻量级进程就是我们通常意义上所讲的线…
Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就需要了解一些底层的知识来进行错误排查. 自动内存管理机制:介绍内存是如何划分的. 垃圾收集器与内存分配策略:分析垃圾收集算法. 虚拟机性能监控与故障处理工具 调优案例分析与实战 第三部分:虚拟机执行子系统 类文件系统:介绍Class文件结构的各个组成部分. 虚拟机类加载机制:介绍类加载过程的各个阶段…
  一.对象的内存布局 已主流的HotSpot虚拟机来说,   在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 1.对象头(Header)     HotSpot虚拟机的对象头包括两部分信息,         第一部分用于存储对象自身的运行时数据,如哈希码(HashCode).GC分代年龄.锁状态标志.线程持有的锁.偏向线程ID.偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(…
在c++发明的初期对于c++对象模型的争论从来没有停止过直到标准委员会通过了最终的c++对象模型这件事情才变得尘埃落定.C++对象模型可能是最不需要去解释的,但是又是不得不去说的因为c++的入门最先接触的就是c++对象.在上个世纪一共有三种c++对象模型,它们的出现可以说是一个不断优化的过程最终只有我们目前看到的c++对象模型在使用.了解c++对象模型非常重要,了解之后对于对象的内存布局,内存大小,虚函数以及静态数据成员和成员函数的理解有非常巨大的帮助.言归正传,下面就来分别讨论c++的三种对象…
一.对象的内存布局 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 从上面的这张图里面可以看出,对象在内存中的结构主要包含以下几个部分: Mark Word(标记字段):对象的Mark Word部分占4个字节,其内容是一系列的标记位,比如轻量级锁的标记位,偏向锁标记位等等. Klass Pointer(Class对象指针):Class对象指针的大小也是4个字节,其指向的位置是对象对应的C…
深入理解Java对象(理清关系) 1.对象的创建过程: 所有创建过程如下所示: new 类名 根据new的参数在常量池中定位一个类的符号引用. 如果没有找到这个符号引用,说明类还没有被加载,则进行类的加载.解析和初始化. 虚拟机为对象分配内存(位于堆中) 将分配的内存初始化为零值(不包括对象头) 调用对象的<init>方法(包括代码块和构造方法) 2.如何给对象分配内存 1.指针碰撞 系统按照指针移动来分配内存. 2.空闲列表 系统需要维护一个链表,来维护哪些模块可用,以便分配内存 3.线程安…
对象头 class oopDesc { ... private: volatile markOop _mark; union _metadata { Klass* _klass; narrowKlass _compressed_klass; } _metadata; ... } 在hotspot中对象指针称为oop(ordinary object pointer),而oopDesc则是对象头的结构..除了Klass(之所以叫klass是因为class是C++关键字)指针外,,还由一个_mark字…
JAVA | Java对象的内存分配过程是如何保证线程安全的? 专注于Java领域优质技术,欢迎关注 作者 l Hollis 来源 l Hollis(ID:hollischuang) JVM内存结构,是很重要的知识,相信每一个静心准备过面试的程序员都可以清楚的把堆.栈.方法区等介绍的比较清楚. 上图,是一张在作者根据<Java虚拟机规范(Java SE 8)>中描述的JVM运行时内存区域结构画的. 很多人都知道Java对象是在堆内存中分配空间的(JIT优化除外),也知道内存分配过程中是线程安全…
原文地址:http://blog.csdn.net/haoel/article/details/3081328 C++ 对象的内存布局 陈皓 http://blog.csdn.net/haoel 前言 07年12月,我写了一篇<C++虚函数表解析>的文章,引起了大家的兴趣.有很多朋友对我的文章留了言,有鼓励我的,有批评我的,还有很多问问题的.我在这里一并对大家的留言表示感谢.这也是我为什么再写一篇续言的原因.因为,在上一篇文章中,我用了的示例都是非常简单的,主要是为了说明一些机理上的问题,也是…