zoukankan      html  css  js  c++  java
  • Java中对象在内存中的大小、分配等问题

    Java创建一个对象的过程

    1. 是否对象指向的类已经加载到内存了
      1. 如果没有加载,就要经过load、linking(verification、preparation、resolution)、initializing把类加载进内存中。
    2. 为对象分配内存空间、成员变量赋默认值
    3. 执行构造方法
      1. 成员变量赋指定值
      2. 执行构造方法语句

    对象在内存中的存储布局(这里指在64位的JVM中)

    普通对象

    1. 对象头:
      1. markwork 8个字节
      2. ClassPointer指针 JVM默认开启了 -XX:userCompressedClassPoniters参数,把ClassPointer指针从8个字节压缩到4个字节
    2. 实例数据
      1. 引用类型 JVM默认开启了 -XX:userCompressedOops参数,把原本普通引用类型指针从8个字节压缩到4个字节
    3. Padding对齐,将对象大小对齐到8的倍数

    数组

    1. 对象头:
      1. markword 8个字节
      2. ClassPointer指针 (如上)
      3. 数组大小 4个字节
    2. 数组数据
    3. Padding 对齐到8个字节

    markword具体包括什么

    1. 上图中指的是在32位JVM虚拟机中,在64为JVM虚拟机中hashcode占了31位,另外有25位没用过,有一位是没用的,其他都一样
    2. hashcode只有在对象调用了hashcode方法才会计算出hashCode,并把值存入里面。另外需要注意的是,在调用hashCode之后,该对象就不能进入偏向锁,因为偏向锁中需要记录线程ID,和线程重入次数(Epoch),但是他们位置被hashCode占了
    3. JVM中默认GC年龄最大为15,是因为如果所示,分代年龄只有4位,最大表示15。

    对象如何定位

    1. 通过句柄池

      ​ 使用句柄池最大的好处是reference存储的是稳定的句柄池地址,在因为GC之后对象被移动了只需要改变句柄池中指向实例数据的地址。

    2. 通过直接指针

      ​ 使用直接指针访问的好处是速度更快,节省了一次指针定位的时间开销,就虚拟机HotSpot而言,它主要使用第二种方式进行对象访问。但是当对象因为GC而被移动位置后,所用指向这个对象的引用都要改变引用地址。

  • 相关阅读:
    让脚本在后台运行的方式
    inotify+rsync文件实时同步报错:usr/local/bin/inotifywait: error while loading shared libraries: libinotifytools.so.0:
    简单使用zabbix监控nginx是否存活
    zabbix4.0添加磁盘io监控
    文本处理三剑客之awk(No.1)
    对比各节点host 与 标准节点host差异脚本
    hdfs standby namenode checkpoint 的一些参数
    hdfs dfsadmin 命令详解
    hive grouping sets 实现原理
    dbcp 连接池参数说明
  • 原文地址:https://www.cnblogs.com/zcr-xiaozhai/p/13816054.html
Copyright © 2011-2022 走看看