怎样创建旅游网站,产品开发流程及每个流程内容,网站开发中可能遇到的技术问题,自己可以做拼单网站吗文章目录 1. 类加载检查2. 内存分配① 指针碰撞② 空闲列表线程安全问题#xff1a; 3. 内存空间初始化4. 对象头设置5. 对象初始化 当Java虚拟机遇到一条
new指令时#xff0c;会执行以下步骤来创建对象#xff1a; 1. 类加载检查
首先检查new指令的参数是否能在常量池中… 文章目录 1. 类加载检查2. 内存分配① 指针碰撞② 空闲列表线程安全问题 3. 内存空间初始化4. 对象头设置5. 对象初始化 当Java虚拟机遇到一条
new指令时会执行以下步骤来创建对象 1. 类加载检查
首先检查new指令的参数是否能在常量池中定位到一个类的符号引用并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有必须先执行相应的类加载过程。
2. 内存分配
内存分配有两种方式
① 指针碰撞
如果Java堆内存是规整的所有被使用过的内存都被放在一 边空闲的内存被放在另一边中间放着一个指针作为分界点的指示器那所分配内存就仅仅是把那 个指针向空闲空间方向挪动一段与对象大小相等的距离这种分配方式称为“指针碰撞”Bump The Pointer)。
② 空闲列表
如果Java堆内存不规整已被使用的内存和空闲的内存相互交错在一起那就没有办法简单地进行指针碰撞了虚拟机就必须维护一个列表记录上哪些内存块是可用的在分配的时候从列表中找到一块足够大的空间划分给对象实例并更新列表上的记录这种分配方式称为“空闲列表”Free List。 内存是否规整取决于垃圾收集器是否带有压缩整理功能。例如Serial和ParNew等带有Compact过程的收集器采用“指针碰撞”而CMS这种基于Mark-Sweep算法的收集器通常采用“空闲列表”。 线程安全问题 除了分配方式外由于对象创建在虚拟机中是一个非常频繁的行为此时需要保证在并发环境下的线程安全如果一个线程给对象 A 分配了内存空间但指针还没来得及修改此时就可能出现另外一个线程使用原来的指针来给对象 B 分配内存空间的情况。想要解决这个问题有两个方案 方式一采用同步锁定或采用 CAS 配上失败重试的方式来保证更新操作的原子性。 CAS操作的基本逻辑是 1比较某个变量的当前值是否等于预期值。 2如果相等则将该变量更新为新值。 3如果不相等则返回当前值调用方可以选择重 方式二每个线程在Java堆中预先分配一小块内存称为本地线程分配缓冲Thread Local AllocationBufferTLAB哪个线程要分配内存就在哪个线程的本地缓冲区中分配TLAB是线程私有的内存缓冲区只有本地缓冲区用完了分配新的缓存区时才需要同步锁定。
3. 内存空间初始化
分配内存后虚拟机会将分配到的内存空间初始化为零值如果使用了TLAB的话这一项工作也可以提前至TLAB分配时顺便进行。
4. 对象头设置
设置对象头信息包括对象的类元数据指针、哈希码、GC分代年龄等。
5. 对象初始化
在上面工作都完成之后从虚拟机的视角来看一个新的对象已经产生了。但是从Java程序的视角看来对象创建才刚刚开始——构造函数即Class文件中的init()方法还没有执行new指令之后会接着执行init()方法按照程序员的意愿对对象进行初始化。