精华内容
下载资源
问答
  • Java对象

    2020-06-23 15:24:01
    java对象结构:对象头,对象实际数据,对齐填充。 markwork:用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位...

    在这里插入图片描述
    java对象结构:对象头,对象实际数据,对齐填充。
    markwork:用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,官方称它为“MarkWord”。

    klass
    对象头的另外一部分是klass类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.

    数组长度(只有数组对象有)
    如果对象是一个数组, 那在对象头中还必须有一块数据用于记录数组长度.

    实例数据:真正的数据,无论是定义的还是继承来的,在此处都会被记录。

    对齐填充:填充数据,将Java对象整体大小填充为8字节的倍数。HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍。
    为了提高性能,每个对象的起始地址都对齐于8字节,当封装对象的时候为了高效率,对象字段声明的顺序会被重排序成下列基于字节大小的顺序:

    double (8字节) 和 long (8字节)
    int (4字节) 和 float (4字节)
    short (2字节) 和 char (2字节):char在java中是2个字节。java采用unicode,2个字节(16位)来表示一个字符。
    boolean (1字节) 和 byte (1字节)
    reference引用 (4/8 字节)
    <子类字段重复上述顺序>
    子类字段重复上述顺序。

    有时候部分数据会被提前,例如int被提前,原因一般为放到前面填充对象头,使对象头字节数符合规范。

    HotSpot对象模型
    HotSpot中采用了OOP-Klass模型,它是描述Java对象实例的模型,它分为两部分:

    类被加载到内存时,就被封装成了klass,klass包含类的元数据信息,像类的方法、常量池这些信息都是存在klass里的,你可以认为它是java里面的java.lang.Class对象,记录了类的全部信息;
    OOP(Ordinary Object Pointer)指的是普通对象指针,它包含MarkWord 和元数据指针,MarkWord用来存储当前指针指向的对象运行时的一些状态数据;元数据指针则指向klass,用来告诉你当前指针指向的对象是什么类型,也就是使用哪个类来创建出来的;

    那么为何要设计这样一个一分为二的对象模型呢?这是因为HotSopt JVM的设计者不想让每个对象中都含有一个vtable(虚函数表),所以就把对象模型拆成klass和oop,其中oop中不含有任何虚函数,而klass就含有虚函数表,可以进行method dispatch。

    一个Java对象在内存中的布局可以连续分成两部分:instanceOop(继承自oop.hpp)和实例数据;
    通过栈帧中的对象引用reference找到Java堆中的对象,再通过对象的instanceOop中的元数据指针klass来找到方法区中的instanceKlass,从而确定该对象的类型。

    执行new A()的时候,JVM 做了什么工作。首先,如果这个类没有被加载过,JVM就会进行类的加载,并在JVM内部创建一个instanceKlass对象表示这个类的运行时元数据(相当于Java层的Class对象)。初始化对象的时候(执行invokespecial A::),JVM就会创建一个instanceOopDesc对象表示这个对象的实例,然后进行Mark Word的填充,将元数据指针指向Klass对象,并填充实例变量。

    元数据—— instanceKlass 对象会存在元空间(方法区),而对象实例—— instanceOopDesc 会存在Java堆。Java虚拟机栈中会存有这个对象实例的引用。
    ————————————————
    原文链接:https://blog.csdn.net/zqz_zqz/article/details/70246212

    展开全文
  • jvm系列序本文主要简述Java对象的内存布局以及其大小的计算。Java对象内存布局在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头...

    jvm系列

    本文主要简述Java对象的内存布局以及其大小的计算。

    Java对象内存布局

    8a28b21379d1d82ae4356042d82eb0b3.png

    在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

    对象头

    HotSpot虚拟机的对象头包括两部分信息:

    第一部分markword,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit,官方称它为“MarkWord”。

    对象头的另外一部分是klass,类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例.

    实例数据

    实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中定义的,都需要记录起来。

    对齐填充

    第三部分对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。而对象头部分正好是8字节的倍数(1倍或者2倍),因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

    对象大小计算

    要点

    在32位系统下,存放Class指针的空间大小是4字节,MarkWord是4字节,对象头为8字节。

    在64位系统下,存放Class指针的空间大小是8字节,MarkWord是8字节,对象头为16字节。

    64位开启指针压缩的情况下,存放Class指针的空间大小是4字节,MarkWord是8字节,对象头为12字节。

    数组长度4字节+数组对象头8字节(对象引用4字节(未开启指针压缩的64位为8字节)+数组markword为4字节(64位未开启指针压缩的为8字节))+对齐4=16字节。

    静态属性不算在对象大小内。

    实例

    import java.util.HashMap;

    /**

    * 64位开启指针压缩的话,markword变成8字节,压缩了class指针为4字节,故对象头12字节

    * 64位没有开启指针压缩的话,markword8字节,class指针8字节,对象头16字节

    * 32位markword为4字节,class指针为4字节,对象头8字节

    *

    * 另外,静态属性所占用的空间通常不算在对象本身,因为它的引用是在方法区。

    *

    * @author xixicat

    * @created 2014-10-03

    */

    public class ObjectSize {

    public static void main(String[] args){

    System.out.println(SizeOfTool.getObjectSize(new A(),SizeEnum.B));

    System.out.println(SizeOfTool.getObjectSize(new B(),SizeEnum.B));

    System.out.println(SizeOfTool.getObjectSize(new C(),SizeEnum.B));

    System.out.println(SizeOfTool.getObjectSize(new D(),SizeEnum.B));

    System.out.println(SizeOfTool.getObjectSize(new E(),SizeEnum.B));

    System.out.println(SizeOfTool.getObjectSize(new Q(),SizeEnum.B));

    /**

    * 64位压缩指针下,对象头12字节,数组长度描述4字节,数据4*100 =16+400 = 416

    */

    System.out.println(SizeOfTool.getObjectSize(new int[100],SizeEnum.B));

    /**

    * 属性4位对齐

    * 64位压缩指针下,对象头12字节,数组长度描述4字节,数据1*100,对齐后104 = 16+104 = 120

    */

    System.out.println(SizeOfTool.getObjectSize(new byte[100],SizeEnum.B));

    /**

    * 二维数组

    * 64位指针压缩下

    * 第1维数组,对象头12字节,数组长度描述4字节,2个数组引用共8字节,共24字节

    * 第2维数组,对象头12字节,数组长度描述4字节,100个数组引用共400字节,对齐后共416字节

    * 第1维的2个引用所指对象大小 = 2*416 = 832 字节

    * 共24+832 = 856字节

    */

    System.out.println(SizeOfTool.getObjectSize(new int[2][100],SizeEnum.B));

    /**

    * 二维数组

    * 64位指针压缩下

    * 第1维数组,对象头12字节,数组长度描述4字节,100个数组引用共400字节,共416字节

    * 第2维数组,对象头12字节,数组长度描述4字节,2个数组引用共8字节,共24字节

    * 第1维的100个引用所指对象大小 = 100*24 = 2400 字节

    * 共416+2400 = 2816字节

    */

    System.out.println(SizeOfTool.getObjectSize(new int[100][2],SizeEnum.B));

    System.out.println(SizeOfTool.getObjectSize(new Object(),SizeEnum.B));

    /**

    * 不算static属性

    * private final char value[];

    * private int hash; // Default to 0

    * private transient int hash32 = 0;

    *

    * 32位下,String对象头8字节,2个int类型8字节,char数组引用占4字节,共占24字节

    * 另外,还要算上value[]数组的占用,数组对象头部8字节,数组长度4字节,对齐后共占16字节

    * =》String对象对象大小24+16 = 40字节

    * 64位开启指针压缩下(压缩指针),String对象头12字节,2个int类型8字节,char数组引用占4字节,共占24字节

    * 另外,还要算上value[]数组的占用,数组对象头部12字节,数组长度4字节,对齐后共占16字节

    * =》String对象大小24+16=40字节

    */

    System.out.println(SizeOfTool.getObjectSize(new String(),SizeEnum.B));

    /**

    * transient Entry[] table = (Entry[]) EMPTY_TABLE;

    * transient int size;

    * int threshold;

    * final float loadFactor;

    * transient int modCount;

    *

    * 64位开启指针压缩下,对象头部12字节,数组引用4字节,3个int12字节,float4字节,共32字节

    * 另外,算上Entry[] = 对象头12 +属性16字节+数组长度4字节 = 32字节

    *

    * final K key;

    * V value;

    * Entry next;

    * int hash;

    *

    * 对象头12字节,3个引用共12字节,1个int4字节 =》 一个entry至少占用28字节

    *

    * =》32+32=64字节

    */

    System.out.println(SizeOfTool.getObjectSize(new HashMap(),SizeEnum.B));

    }

    }

    //32位下对象头8字节,byte占1字节,对其填充后,总占16字节

    //64位开启指针压缩下对象头12字节,byte1字节,对齐后占16字节

    class A{

    byte b1;

    }

    //32位下对象头8字节,8个byte8字节,总16字节

    //64位开启指针压缩下对象头12字节,8个byte8字节,对齐后占24字节

    class B{

    byte b1,b2,b3,b4,b5,b6,b7,b8;

    }

    //32位下对象头8字节,9个byte9字节,对其填充后,总24字节

    //64位开启指针压缩下对象头12字节,9个byte9字节,对齐后占24字节

    class C{

    byte b1,b2,b3,b4,b5,b6,b7,b8,b9;

    }

    //32位下对象头8字节,int占4字节,引用占4字节,共16字节

    //64位开启指针压缩下对象头12字节,int占4字节,引用占4字节,对齐后占24字节

    class D{

    int i;

    String str;

    }

    //32位下对象头8字节,int4字节,byte占1字节,引用占4字节,对其后,共24字节

    //64位开启指针压缩下对象头12字节,int占4字节,引用占4字节,byte占1字节,对齐后占24字节

    class E{

    int i;

    byte b;

    String str;

    }

    /**

    * 对齐有两种

    * 1、整个对象8字节对齐

    * 2、属性4字节对齐 ****

    *

    * 对象集成属性的排布

    * markword 4 8

    * class指针 4 4

    * 父类的父类属性 1 1

    * 属性对齐 3 3

    * 父类的属性 1 1

    * 属性对齐 3 3

    * 当前类的属性 1 1

    * 属性对齐填充 3 3

    * 整个对象对齐 8+12 =》 24 12+12=》24

    */

    class O{

    byte b;

    }

    class P extends O{

    byte b;

    }

    class Q extends P{

    byte b;

    }

    参考

    展开全文
  • java对象

    2017-08-17 17:38:42
    掌握结构化的编程java思想万物皆对象的思想对象与类对象:用来描述客观事物的一个实体,由一组属性和方法构成. 属性—对象具有的各种特征 每个对象的每个属性都有特性的值. 例如.张三和李四的年龄和体重都不同 方法...

    目的:
    了解类和对象和之间的关系
    掌握定义类和对象的方法
    掌握结构化的编程

    java思想

    万物皆对象的思想

    对象与类

    对象:用来描述客观事物的一个实体,由一组属性和方法构成.
    属性—对象具有的各种特征

        每个对象的每个属性都有特性的值.
        例如.张三和李四的年龄和体重都不同
    

    方法—对象执行的操作

        类是对象概括.是对象的分类
        具体相同属性和方法的一组对象的集合
        是概念模型.描述对象拥有的特征(属性)和行为(方法)
    

    类和对象的关系:

    类是对象的描述,对象是类的个体;
    类是抽象的,对象是具体的;
    程序中由类产生对象;
    面向对象一共有三个特征:封装.继承.多态.
    

    基本步奏

    • 定义类
    • 构造对象
    • 使用对象

    类的定义

    UML图:类关系图:类.属性.方法

    • 类 : class leiming { };
    • 属性 : 数据类型 变量名;
    • 方法 : void | 返回值类型 方法名 ;
    public class Person {
        // 属性
        String name;
        int age;
    
        // 方法
        public void eat() {
            System.out.println("我喜欢吃蛋炒饭");
        }
    
        public void say(String content) {
            System.out.println("我的名字" + name);
            System.out.println("我的年龄" + age);
        }
    
    }

    构造对象

    格式:类名:对象名 = new 类名();
    例如:Person zhangSan = new Person();
    内存结构:对象名在栈里。属性和方法在堆里。

    对象的使用

    格式:对象.属性 ;  
         对象.方法 ;
    

    类的组成

    • 属性
    • 方法
    • 构造函数
      • 格式:public 类名(参数列表){ }
      • 特点:
        • 和泪同名
        • 没有返回值
      • 功能
    展开全文
  • JAVA对象内存结构HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头markWord用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC...

    JAVA对象内存结构

    HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

    7b8c5785da1f609ffc34c4c39c264290.png

    对象头

    markWord

    用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,这部分数据的长度在32位和64位的虚拟机(暂 不考虑开启压缩指针的场景)中分别为32个和64个Bits。

    Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。

    无锁状

    83f0d1860c18937277aa7a0f49bd9025.png

    加锁状态

    84884fdbe32c0747f510c4583666b592.png

    其中轻量级锁和偏向锁是Java6 对 synchronized 锁进行优化后新增加的,稍后我们会简要分析。这里我们主要分析一下重量级锁也就是通常说synchronized的对象锁,锁标识位为10,其中指针指向的是monitor对象(也称为管程或监视器锁)的起始地址。每个对象都存在着一个 monitor 与之关联,对象与其 monitor 之间的关系有存在多种实现方式,如monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成,但当一个 monitor 被某个线程持有后,它便处于锁定状态。在Java虚拟机(HotSpot)中,monitor是由ObjectMonitor实现的,其主要数据结构如下(位于HotSpot虚拟机源码ObjectMonitor.hpp文件,C++实现的)

    ObjectMonitor() {

    _header = NULL;

    _count = 0; //记录个数

    _waiters = 0,

    _recursions = 0;

    _object = NULL;

    _owner = NULL;

    _WaitSet = NULL; //处于wait状态的线程,会被加入到_WaitSet

    _WaitSetLock = 0 ;

    _Responsible = NULL ;

    _succ = NULL ;

    _cxq = NULL ;

    FreeNext = NULL ;

    _EntryList = NULL ; //处于等待锁block状态的线程,会被加入到该列表

    _SpinFreq = 0 ;

    _SpinClock = 0 ;

    OwnerIsThread = 0 ;

    }

    ObjectMonitor中有两个队列,_WaitSet 和 _EntryList,用来保存ObjectWaiter对象列表( 每个等待锁的线程都会被封装成ObjectWaiter对象),_owner指向持有ObjectMonitor对象的线程,当多个线程同时访问一段同步代码时,首先会进入 _EntryList 集合,当线程获取到对象的monitor 后进入 _Owner 区域并把monitor中的owner变量设置为当前线程同时monitor中的计数器count加1,若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 WaitSet集合中等待被唤醒。若当前线程执行完毕也将释放monitor(锁)并复位变量的值,以便其他线程进入获取monitor(锁)。如下图所示

    28707523fb58c80f997afb4856d1e0e4.png

    由此看来,monitor对象存在于每个Java对象的对象头中(存储的指针的指向),synchronized锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因,同时也是notify/notifyAll/wait等方法存在于顶级对象Object中的原因。

    展开全文
  • 一个Java 对象在在内存中的存储布局分为3 块区域(HostSpot VM):1. 对象对象头的信息主要包括两个部分:Mark Word类型指针数组长度(如果是数组才有)1.1 Mark WordMark Word 的定义:Mark Word 用于存储对象自身的...
  • Java对象

    2019-08-20 18:07:26
    Java对象头 1、存储结构 32位的JVM Mark Word的存储结构为: 锁状态 25bit 4bit 1bit是否是偏向锁 2bit标志位 无锁状态 对象的HashCode 对象的分代年龄 0 01 在同步的时候获取对象的monnitor,即获取到...
  • 成员函数有getAge(),功能是实现计算到2017年12月25日时该Birthday对象年龄。编写程序测试这个类。输入格式: 输入出生的年、月、日(注:输入的年月日以换行隔开)输出格式: 计算得到年龄输入样例: 在这...
  • 概念 在HotSpot虚拟机中,对象在内存...第一部分Mark Word,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚
  • java对象结构

    2019-09-17 03:23:25
    java对象在内存中占用字节 以64位为例 对象在内存中的结构 其中对象头包括:markword (_mark)和class对象指针(_klass) 1.markword:占用8个字节 用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代...
  • 【运行结果】:【运行结果】姓名:rollen年龄:20姓名:hello world年龄:100姓名:hello world年龄:100下面看看java中的浅拷贝对于类中的每个域,如果只包含基本类型或者不可变的引用类型,如String,或者对象在其...
  • Java对象详解

    2019-01-21 21:56:44
    一、Java对象的组成 1.对象头 运行时数据 存储对象运行时的数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据官方成为“Mark Word”,它的长度在32位和64位的...
  • Java对象头结构

    2020-11-29 14:57:41
    java对象java对象头长度 长度 内容 说明 32/64bit Mark Word 储存对象的hashcode等信息 32/64bit Class Metadata Address 储存到对象数据类型的指针 32/64bit Array length 数组的长度 Mark Word...
  • 对象头MarkWord(标记字段):哈希码、分代年龄、锁标志位、偏向线程ID、偏向时间戳等信息。Mark Word被设计成了一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。...
  • Java对象的创建

    2021-02-21 22:01:26
    Java对象的创建对象的创建创建流程Java堆分配内存的两种方式对象内存布局对象头实例数据对齐填充对象访问定位方式对象访问方式访问方式对比 对象的创建 创建流程 虚拟机遇到一条new指令时,首先检查这个对应的类...
  • JAVA 对象大小

    2018-07-09 09:10:08
    写在前面看了网上很多描述,其实已经写的很详细了,但是自己没有实践过总是觉得有点蒙蒙的概念Java对象的内存布局:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)。虚拟机的对象头包括两部分...
  • 如果想要了解java对象在内存中的大小,必须先要了解java对象的结构。 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding) java 对象头...
  • 对象头MarkWord(标记字段):哈希码、分代年龄、锁标志位、偏向线程ID、偏向时间戳等信息。Mark Word被设计成了一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。...
  • 1. 内存布局在HotSpot虚拟机中,对象的内存布局可以分为三部分:对象头(Header)、 实例...如哈希码、GC分代年龄、锁状态标示、线程持有的锁等。这部分数据的长度在32bit和64bit虚拟机上分别为32bit和64bit。官方称...
  • java 对象排序

    2016-03-29 12:32:09
    //输出学生对象的时候,需要先按照年龄排序,如果年龄相同,则按照姓名排序,如果姓名也相同,则按照学号排序 import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public ...
  • Java对象内存布局

    2020-03-13 00:36:49
      在Java虚拟机中,每一个Java对象都由标记字段(markword)、类型指针(class pointer)、实例数据(instance data)和内存对齐(padding)构成,数组对象还有数组长度(length,4字节)。markword里主要存储...
  • JAVA对象锁升级过程

    2021-02-22 21:28:29
    JAVA对象锁升级过程 java对象被锁定的状态有四种,且锁状态存储在对象头的markWord中,锁状态等级由低到高分别为: 无锁状态 : markWord存储 对象的hashCode、分代年龄、是否偏向锁、锁标标志位 偏向锁状态:mark...
  • JAVA对象内存布局 以及对象定位 1、Java对象内存布局  在hotSpot虚拟机中,对象在内存中的布局可以分成对象头、实例数据、对齐填充三部分。  对象头:对象头包含两部分,第一部分主要包括对象自身的运行行元数据...
  • Java对象结构

    2018-11-21 17:27:22
    在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data...第一部分markword,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程...
  • 对象的内存分配,往大的方向上讲,就是在堆上分配,少数情况下也可能会直接分配在老年代中,分配的规则并不是百分之百固定的,其细节决定于当前使用的是哪种垃圾收集器组合,当然还有虚拟机中与内存相关的参数。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,898
精华内容 1,159
关键字:

java对象年龄

java 订阅