电商网站开发服务器,seo顾问是啥,wordpress 自定义登陆页面,网络舆情的三种分类标准如你所知#xff0c;Java是一门面向对象的编程语言。我们平常在写代码的时候也是在不停的操作各种对象#xff0c;那么当你在写出User user new User();这样一行代码的时候#xff0c;JVM都做了些什么呢#xff1f;
作者#xff1a;湖人总冠军 一、引言
如你所知#…如你所知Java是一门面向对象的编程语言。我们平常在写代码的时候也是在不停的操作各种对象那么当你在写出User user new User();这样一行代码的时候JVM都做了些什么呢
作者湖人总冠军 一、引言
如你所知Java是一门面向对象的编程语言。我们平常在写代码的时候也是在不停的操作各种对象那么当你在写出User user new User();这样一行代码的时候JVM都做了些什么呢? 二、了解对象
1、内存布局
在Hotspot虚拟机中一个对象的内存布局分为三个部分对象头、实例数据、对齐填充。
对象头又有两部分的信息第一部分是用于存储对象自身的运行数据(HashCode、GC分代年龄、锁状态标志等)。另一部分是类型指针指向它的类元数据虚拟机通过这个指针确定这个对象是哪个类的实例(如果使用句柄池方式则不会有)。如果是数组还会有一个记录数组长度的如下表所示Mark Word是一个非固定的数据结构以便在极小的空间内存储尽量多的信息它会根据对象的状态复用自己的存储空间。各状态下的存储内容如下表所示 实例数据部分是真正存储的有效信息就是在代码中定义的各种类型的字段内容。无论是父类继承下来的还是在子类中的。对齐填充不是必须存在的仅仅起着占位符的作用因为HotSpot虚拟机要求对象的起始地址必须是8字节的整数倍。
2、对象的访问
Java程序中我们操作一个对象是通过指向这个对象的引用。我们都知道对象存在堆中这个引用存在虚拟机栈中。那么引用通过什么方式去定位堆中对象的位置呢?
直接指针法(HotSpot实现)引用中直接存储的就是堆中对象的地址。好处就是一次定位速度快缺点是对象移动(GC时对象移动)引用本身需要修改。句柄法Java堆中划分出一部分作为句柄池引用存储的是对象的句柄地址而句柄中包括了对象实例和类型的具体位置信息。好处是对象移动只会改变句柄中的实例数据指针缺点是两次定位。三、创建对象流程
上面介绍了对象的基本信息现在来讲一讲创建对象的流程 当虚拟机遇到一条new指令时会去检查这个指令的参数能否在常量池中定位到一个类的符号引用并检查代表的类是否已经被类加载器加载。如果没有被加载那么必须先执行这个类的加载。类加载检查通过后虚拟机将为新对象分配内存对象所需内存的大小在类加载后便可以确定。内存分配完成后虚拟机需要将对象初始化为零值保证对象的实例变量在代码中不赋初始值就能直接使用。类变量在类加载的准备阶段初始化为零值。对对象头进行必要信息的设置比如如何找到类的元数据信息、对象的HashCode、GC分代年龄等。经过上述操作一个新的对象已经产生但是方法还没有执行所有的字段都是零值。这时候需要执行方法(构造方法)把对象按照程序员的意愿进行初始化。类变量的初始化操作在类加载的初始化阶段方法完成
分配内存有两种方式
Java堆内存是规整的(使用标记整理或带压缩的垃圾收集器)使用一个指针指向空闲位置分配内存既将指针移动与分配大小相等的距离内存不是规整的(使用标记清除的垃圾收集器)虚拟机维护一个可用内存块列表分配内存时从列表中找到一个足够大的内存空间划分给对象并更新可用内存列表。
无法找到足够的内存时会触发一次GC
分配内存时并发问题解决方案
对分配内存空间的动作进行同步操作---采用CAS失败重试的方式保证更新操作的原子性。每个线程在堆中预先分配一块小内存称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)哪个线程要分配内存就在它的TLAB上分配只有TLAB用完并分配新的TLAB时才需要同步锁定。通过-XX:/-UseTLAB参数来设定。
四、创建对象指令重排序问题
A a new A();
new一个对象的简单分解动作
分配对象的内存空间初始化对象设置引用指向分配的内存地址
其中2、3两步间会发生指令重排序导致多线程时如果在初始化之前访问对象则会出现问题单例模式的双重检测锁模式正是会存在这个问题。可以使用volatile来禁止指令重排序解决问题
阅读目录置顶)(长期更新计算机领域知识
阅读目录置顶)(长期更新计算机领域知识
阅读目录置顶)(长期科技领域知识
歌谣带你看java面试题