zoukankan      html  css  js  c++  java
  • 对象的创建

    对象的创建

    当虚拟机遇到一条 字节码new指令时,

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

    2. 并检查这个符号引用代表的类是否已被 加载、解析、初始化过,如过没有,必须执行相应的类加载过程;

    3. 在类加载检查通过之后,虚拟机将会为新生对象分配内存

      • 对象所需的内存在类加载后就可以完全确定;

      • 为对象分配内存其实就是在堆上划分出一个确定大小的内存

      • 有两种分配内存的方式:

        • “指针碰撞”:堆内存规整,垃圾收集器带有空间压缩整理能力(Serial、ParNew)

        • “空闲列表“:堆内存不规整,垃圾收集器不带空间压缩整理能力(CMS 基于”清除swap“算法)

      虚拟机创建对象内存分配时的线程安全问题的解决:

      • 对分配内存空间的动作进行同步处理。实际上,虚拟机采用CAS配上失败重试的方式保证更新操作的原子性

      • 把内存分配的动作按照线程划分到不同的空间中进行。即每个线程在java堆中预先一小块内存,称为本地线程分配缓存(Thread Local Allocation Buffer,TLAB)分配内存时在该线程的本地缓冲区分配,只有本地缓冲区用完了,分配新的缓冲区时才需要同步锁定。虚拟机是否使用TLAB,可以通过 -XX:+/-UseTLAB参数来设定。

    4. 内存分配完成后,虚拟机必须将分配到的内存空间(不包括对象头)都初始化为零值。如果使用了TLAB,这个步骤可以提前至TLAB分配时顺便进行。这个步骤保证了对象的实例字段可以不赋初值就直接使用。

    5. 接下来,虚拟机需要对对象进行必要的设置,例如,这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码(实际上对象的哈希码会延后到真正调用Object::hashCode()方法是时才计算)、对象的GC分代年龄等信息。这些信息存放在对象头(Object Header)中。

    6. 上述工作完成之后,Class文件的<init>()方法还没有执行,所有的字段都是默认值。new之后会接着执行<init>()方法按照程序员的意愿对对象进行初始化,这样一个真正可用的对象才算被构造出来

    总结:new一个对象包括:类是否加载、为对象分配内存、并发处理、内存空间初始化、对象设置、<init>()等步骤

  • 相关阅读:
    数据结构--线性表和链表的基础知识
    OC基础--字符串
    iOS开发知识梳理博文集
    OC基础--数据类型与表达式
    数据结构概述
    数据结构--栈和队列基础知识
    NodeJS Get/Post 参数获取
    NodeJS + express 添加HTTPS支持
    NodeJS 获取系统时间 并格式化输出
    Node.Js + Express 搭建服务器
  • 原文地址:https://www.cnblogs.com/learnjavajava/p/14505713.html
Copyright © 2011-2022 走看看