一、对象的内存布局

对象的内存结构又可以被分为:对象头,实例数据,对象填充

对象头:对象头结构在32位JVM与64位JVM中的实现细节是不同的

32bit:

64bit:

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

对象填充:没有实际意义,仅仅起着占位符的作用。以为对象的大小必须是8字节的整数倍。

二、对象的访问定位

对象的访问定位分为两种:

通过句柄访问对象:

通过指针访问对象:

两种对象访问方式各有优势,使用句柄访问最大好处是reference中存储的是稳定的句柄地址,在对象被移动是只会改变句柄中的实例数据指针,而reference本身不需要修改。

使用直接指针访问方式的最大好处是速度快,他节省了一次指针定位的时间开销。

三、对象的创建过程

这里主要讨论实例化普通对象的过程,不包括数组和Class对象。

1、检查指令的参数是否可以在常量池中定位到一个类的符号引用

2、检查这个符号引用代表的类是否被加载,解析初始化过

3.1、如果被加载并初始化了继续下一步

3.2、如果没有没有初始化,那么先执行类的加载过程

4、位新生对象分配内存(两种方法)

1)指针碰撞

如果java 堆当中的内存是规则的,已使用内存在一边,未使用内存在另外一边, 中间  放着一个指针作为分界点的指示器,如果需要分配内存就只需要把指针向空闲空间那边挪动一段与对象大小相等的距离

2)空闲列表

如果已用内存和空闲内存是交互存在的,这样虚拟机就必须维护一个列表,记录哪块内存是可用的,在分配内存的时候从列表中找到一个足够大的空间划分给对象实例,并且更新空闲列表。

分配内存时可能出现的问题:并发创建对象会出现指针没来得及修改导致的重复地址覆盖对象

解决办法:分配内存动作同步-采用 CAS配上失败重试方式保证更新操作的原子性

预先给 Java 线程在堆中分配一小块内存,称为本地线程分配缓冲(TLAB),只有当该线程用完才需要同步锁。是否使用 TLAB 可以通过 -XX:+/-UseTLAB

5、将分配到的内存空间都初始化为零值(不包括对象头)

6、对对象进行必要的设置

例如:设置这个对象是哪个类的实例

如何才能找到类的元数据信息

对象的hash码

对象的GC分代年龄

是否启用偏向锁

7、执行方法,可以根据一段代码来讨论变量的具体初始化过程:

class Parent {

private int p_01 = getP_01();

private static int p_02 = getP_02();

{

System.out.println("I am Parent Local code block");

}

static {

System.out.println("I am Parent static code block");

}

public Parent() {

System.out.println("I am Parent Constructor!");

}

private int getP_01() {

System.out.println("p_01 is initialized!");

return 13;

}

private static int getP_02() {

System.out.println("static p_02 is initialized!");

return 14;

}

}

class Son extends Parent {

private int s_01 = getS_01();

private static int s_02 = getS_02();

{

System.out.println("I am Son Local code block");

}

static {

System.out.println("I am Son static code block");

}

public Son() {

System.out.println("I am Son Constructor!");

}

private int getS_01() {

System.out.println("s_01 is initialized!");

return 13;

}

private static int getS_02() {

System.out.println("static s_02 is initialized!");

return 14;

}

}

public class CreateObject {

public static void main(String[] args) {

Son s = new Son();

}

}

执行结果如下:

static p_02 is initialized!

I am Parent static code block

static s_02 is initialized!

I am Son static code block

p_01 is initialized!

I am Parent Local code block

I am Parent Constructor!

s_01 is initialized!

I am Son Local code block

I am Son Constructor!

然后可以总结得出初始化过程如下:

1)父类静态变量,静态代码块执行初始化(静态变量,静态代码按顺序执行,属于同一优先级)

2)子类静态变量,静态代码块执行初始化

3)父类全局变量,代码块被初始化(全局变量,代码按顺序执行,属于同一优先级)

4)父类构造函数执行

5)子类全局变量,代码块被初始化

6)子类构造函数被执行

误区:其实并不是真的子类构造函数在父类构造函数之后执行,而是在子类构造器的第一行隐式调用了父类的构造函数.

java怎么限制一个对象的内存_java对象的内存布局及创建过程相关推荐

  1. java转型 内存_java 对象转型内存分析

    对象转型: 一个基类的引用类型变量可以指向其子类的对象(要求传个动物,传给狗是可以的,狗是动物) 一个基类的引用不可以访问其子类对象的新增成员(狗会游泳不代表所有的动物都会游泳,把狗当作动物来看时不可 ...

  2. java对象内存模型_Java对象的内存模型

    众所周知,函数调用在内存中是通过压栈,退栈实现的,而Java的方法调用则是在JVM栈中通过栈帧实现的,且所有的Java对象都只在堆上分配内存.那么一个Java对象在堆内存里到底长啥样呢?实际上,当一个 ...

  3. java对象的内存分配_java对象在内存的分配问题

    今天看到一个不错的PPT:Build Memory-efficient Java Applications,开篇便提出了一个问题,在Hotspot JVM中,32位机器下,Integer对象的大小是i ...

  4. java对象的内存结构_Java对象在内存中的结构分析

    问题:在Hotspot JVM中,32位机器下,Integer对象的大小是int的几倍? HotSpot虚拟机中,对象在内存中的布局分为三块区域:对象头.实例数据和对齐填充,其中对象头又分为:Mark ...

  5. 动态加载laydate 失效_Java对象的内存布局+反射的原理+动态代理+ 并发和锁+文末彩蛋...

    # 一行代码是怎么运行的 首先,java代码会被编译成字节码,字节码就是java虚拟机定义的一种编码格式,需要java虚拟机才能够解析,java虚拟机需要将字节码转换成机器码才能在cpu上执行. 我们 ...

  6. java nio 堆外内存_Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

  7. java虚拟机的内存_Java虚拟机的内存结构

    我们都知道虚拟机的内存划分了多个区域,并不是一张大饼.那么为什么要划分为多块区域呢,直接搞一块区域,所有用到内存的地方都往这块区域里扔不就行了,岂不痛快.是的,如果不进行区域划分,扔的时候确实痛快,可 ...

  8. java执行内存_java运行时内存

    运行时数据区域 java运行时数据区域主要分为下面几个: 方法区 虚拟机栈 本地方法栈 堆 程序计数器 java运行时数据区域.jpg 程序计数器 它是一块较小的内存空间,可以看做是当前线程所指定的字 ...

  9. java保证一段代码枷锁_Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM ...

最新文章

  1. WPF判断两个时间大小避免误差
  2. 计算机的一些小操作,电脑小白操作中最实用的9个技巧!
  3. BugkuCTF-Misc:宽带信息泄露
  4. 牛客网_PAT乙级_1022挖掘机技术哪家强(20)【class vector sort排序、删除重复元素】
  5. 一文看懂专有网络和交换机的定义及关系
  6. Call for Papers | IEEE/IAPR IJCB 2022 会议
  7. 快速排序(交换排序)-八大排序汇总(6)
  8. 解决mapper映射文件不发布问题
  9. “人,落魄时,千万别装可怜”你怎么看?
  10. java中的命名空间_XPath与Java中的命名空间
  11. GCC Command Options
  12. day20---IO流概述
  13. php微信二次分享出错,解决微信二次分享bug
  14. 初级程序员如何写项目周报和月报
  15. opencv4 python电子书_OpenCV轻松入门面向Python下载-OpenCV轻松入门面向Python电子书pdf免费版-精品下载...
  16. 中级软件设计师知识点总结
  17. OpenFeign简介
  18. 数据控制—完整性约束
  19. iPhone文件管理连接服务器,iOS11文件管理器怎么用?Files文件管理器使用方法与功能介绍...
  20. Android客户端Monkey稳定性测试

热门文章

  1. jQuery实现的简单文字提示效果模拟title
  2. 好的技术文章应该让读者更自信而不是更自卑
  3. 关于邮件服务器应用系统安全SSL ×××(强身份认证)方案
  4. 怎么调整矩形边框宽度_PKPM:梁刚度放大通过放大系数与矩形梁转T形梁的区别...
  5. mysql 自定义排序函数_MySQL自定义排序函数FIELD()
  6. 论文计算机辅助辅助教学应用,计算机辅助教学应用论文.doc
  7. linux裸分区如何区分,Linux 裸设备基础知识
  8. python 遍历内嵌tuple_python内置数据结构list、set、dict、tuple(一)
  9. linux搭建博客Day1
  10. 转行经验分享,关于软件测试的感悟,你想知道的都在这里……