• 对象的创建


    对象的创建

    当虚拟机遇到一条 字节码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>()等步骤

  • 相关阅读:
    IT运维监控解决方案介绍
    Apdex——衡量服务器性能的标准
    服务器监控(包括性能指标与web应用程序)
    使用厂商MIB库查找设备OID值并实施监控的方法
    华为USG6550 MIB CPU MEM
    LInux下实时网络流量监控工具nload教程
    11gR2 集群(CRS/GRID)新功能—— SCAN(Single Client Access Name)
    如何实现网卡bond
    LeetCode(31)-Factorial Trailing Zeroes
    activiti自己定义流程之整合(五):启动流程时获取自己定义表单
  • 原文地址:https://www.cnblogs.com/learnjavajava/p/14505713.html
Copyright © 2020-2023  润新知