您好,登录后才能下订单哦!
本篇文章给大家分享的是有关关于Java对象的创建有什么方法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在方法区常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,就必须先执行相应的类加载过程。
类加载检查过后,虚拟机为新生对象分配内存。对象所需内存大小在类加载过后就完全确定,为对象分配空间就等同于,从Java堆中划分出一块确定大小的内存。
此时有两种情况:
如果Java堆中内存是规整的,那么虚拟机将会采用指针碰撞(BumpthePointer)分配内存。也就是用过的内存放在一边,空闲的内存放另一边,中间有个指针作为分界点指示器,那么分配内存就是把指针向空闲那一边挪动了与对象相同大小的距离。
如果Java堆中内存不规整,已使用和未使用的内存相互交错,那么虚拟机将会采用空闲列表(FreeList)分配内存。也就是虚拟机会维护一个空闲列表,记录哪些内存块可用,分配内存时就从空闲列表中找到一块足够大的空间分给对象实例,并更新列表。
选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整由垃圾收集器是否带有压缩整理功能决定。比如Serial、ParNew这种基于复制算法和标记-整理算法的收集器,就是采用指针碰撞法分配内存。而CMS这种基于标记-清除算法的收集器就是采用空闲列表。
还有一个问题就是要保证分配内存时的线程安全,即使是简单的指针碰撞修改一下指针的位置,在并发情况下也不是线程安全的。解决这个问题有两种方案,一种是对分配内存的动作进行同步处理,保证操作的原子性;另一种就是前面提到的本地线程分配缓冲TLAB。
在Java堆中内存分配完成后,虚拟机会将已分配的内存空间初始化为零值(不包括对象头)。这保证了对象的实例字段在Java代码中可以不用赋初始值就可以直接使用,程序能访问到这些字段的数据类型所对应的零值。如果采用了TLAB,这一步也可以提前至TLAB分配时进行。
接下来对对象进行必要的设置,例如这个对象是哪个类的实例、如何找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息,这些信息都存放在对象的对象头(ObjectHeader)中。
这个时候,从虚拟机的角度看一个新的对象已经产生了,但从Java程序角度看对象的创建才刚开始,init方法还没执行,所有的字段都还为零。所以这时会执行init的方法,把对象按照程序员的意愿初始化。
以上就是关于Java对象的创建有什么方法,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。