jvm中的对象

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jm19920911/article/details/79059585

对象的创建

1 类加载
当虚拟机遇到一条new指令时,先根据这条指令的参数检查常量池中是否有这个类的符号引用,并检查这个类是否被加载,解析和初始化过。如果没有,则先进行类加载过程
符号引用:在编译时,java类并不知道所引用的类的实际地址,因此只能使用符号引用来代替

2 分配内存。
内存的大小在类加载之后便可以确定。此时会有两种情况:1内存规整。即,用过的在一边,未使用的在另一边,中间放一个指针作为分界点,那么此时只需要挪动指针即可,称为“指针碰撞”;2内存不规整。即,已使用和未使用的内存交错,那么虚拟机就维护一个列表,记录已使用和未使用的内存,称为“空闲列表”。使用Serial,ParNew等带有Compact过程的收集器时,java堆是规整的,使用“指针碰撞”;使用CMS这种基于Mark-Sweep算法的收集器,java堆不规整,使用“空闲列表”。
分配内存的时候并非是线程安全的,可能刚给一个对象分配了内存,还没来得及修改指针,另外一个对象就使用原来的指针来分配内存。解决方法有2中:1 jvm采用cas配上失败重试;2 把内存分配的动作按照线程划分在不同的空间,也就是每个线程在堆中先分配一小块内存,称为本地线程分配缓存。分配内存时,现在该线程上的本地缓存上分配,只有本地缓存分配完成并分配新的本地缓存时,才需要同步锁定。
3 初始化内存空间
jvm将分配到的内存空间初始化为0,这一步保证了对象的实力字段在java代码中不赋初始值就能直接使用,程序能访问到这些字段的数据类型所对应的零值
4 设置对象
jvm需要设置的信息包括:对象是哪个类的实例,如何能找到类的元数据信息,对象的哈希码,对象的gc分代年龄等。这些信息存在对象的对象头中。虚拟机当前的运行状态不同,对象头会有不通的设置方式。(运行状态不同指,是否使用偏向锁等)
5 初始化对象
执行new指令之后,紧接着会执行方法,把对象按照程序员的意愿进行初始化

摘抄自《深入理解java虚拟机》

猜你喜欢

转载自blog.csdn.net/jm19920911/article/details/79059585