一、对象创建
类型信息在装载、连接和初始化之后,就可以使用了,可以访问类型的静态字段和方法,可以创建类型实例。对象的创建分为现实创建和隐式创建两种。
显示创建分为:1、通过new创建;2、通过java.lang.Class的newInstance方法创建;3、通过clone方法创建;4、通过java.io.ObjectInputStream的readObject方法创建。
隐式创建分为:1、启动类的main方法的string数组参数;2、常量池的CONSTANT_String_info表项被解析的时候会创建一个String对象;3、每个加载的类都会创建一个java.lang.Class对象;4、字符串+操作的时候,创建StringBuffer/StringBuilder对象。
二、对象在内存中的存储
非严格意义来说,对象都存储在堆上,由垃圾收集器负责回收不在被引用的对象。但是随着jvm运行期编译技术的不断进步,栈上分配对象和标量替换技术使得非逃逸对象可以分配在栈上。当然绝大多数对象都是分配在堆上的,此处我们主要讨论对象在堆中的存储。
对象的内容有:1、实例数据;2、指向堆中类型信息的指针;3、对象锁相关的数据;4、多线程协调完成同一件事情的时候wait set相关的队列;5、垃圾收集相关的内容,如存活时间、finalize方法是否运行过。
对象在内存中存储主要有两种方式:1、堆划分为句柄池和对象池,创建对象后的得到的引用是指向句柄池的指针,句柄池指针则指向对象池里的对象;2、堆只分为对象池,引用直接指向对象池中的对象。具体前边这篇博客已经有描述。这里顺便解答那篇博客中遇到的问题,Integer对象中那个不是实例数据和类型指针的数据是什么。
当然这还是翻书得到的答案,而且也只是HotSpot VM中的那4个字节,被称作对象头,官方称为Mark Word:1、25bits是对象的hashCode;2、4bits是垃圾收集相关的分代年龄;3、2bits是对象锁相关的信息,实现轻量级锁和偏向锁要用到;4、1bit是闲置位,值为0。