正常人都知道,一个Java对象的创建通过new关键字创建。可是,在虚拟机中,一个对象是怎么创建的呢?下面简单的说一下
虚拟机遇到一条new指令时,首先检查该指令的参数是否在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载,解析和初始化过,如果没有,必须先执行相应的类加载过程
对象所需内存的大小在类加载完成后便可确定,从Java堆中划分内存。
1.当Java堆内存规整时,用过与空闲的内存放在两边,中间的指针作为分界点指示器,此时通过指针碰撞(将指针往空闲内存移动一段与对象内存大小相等的距离) 完成内存分配。
2.当Java堆内存不规整时,由虚拟机维护一个空闲列表(Free List),该列表记录了可用的内存块,在分配时从列表中找到一块足够大的内存空间划分给对象实例,并更新列表。
内存分配的线程安全问题
比如,在给A分配内存,指针还未修改,B用了原来的指针分配内存。解决此类问题有两种方案:
1.对分配内存空间的动作进行同步处理
实际上虚拟机通过CAS配上失败重试的方式保证更新操作的原子性。
2.把内存分配的动作按照线程划分在不同的空间之中进行
即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),只有TLAB用完并分配新的时,才需要同步锁定。
-XX:+/-UseTLAB参数设定是否使用TLAB
例如对象是哪个类的实例,如何找到类的元数据信息等,存放在对象的对象头之中。最后通过执行方法,一个对象就产生了