前言:
今天姐妹们对“java创建file对象”大体比较注重,兄弟们都想要了解一些“java创建file对象”的相关文章。那么小编在网上网罗了一些对于“java创建file对象””的相关知识,希望我们能喜欢,大家一起来了解一下吧!对象的创建过程
new对象
image-20230226144541919
1:首先判断这个类有没有加载过,没有加载过的先加载到我们JVM内存中。
2:分配内存
指针碰撞:默认使用,如果JVM堆中内存绝对规整,使用过的内存放一边,空闲的内存放另一边。中间放着指针分界点,在分配内存的时候将那个指针向空闲空间移动一段对象大小的距离。(垃圾收集器用的是标记整理)空闲列表:JVM堆中内存不规整,已使用和未使用的相互交错,没办法用指针碰撞,JVM必须维护一个列表,记录哪些内存块可用,在分配的时候从列表中找到一块足够放下对象的空间给对象实例,并更新列表的记录。(垃圾收集器用的是标记清理)在分配内存的时候,肯定会有并发的问题,不管哪种都存在这种问题,要争抢内存。解决并发问题的方法:1:CAS失败重试。2:本地线程分配缓冲,为了避免争抢,本地线程在堆中划一块自己专属的内存空间,本地线程只往自己的 内存空间中创建对象,默认是开启的,XX:TLABSize 指定TLAB大小,不设置的话默认是Eden的百分之一。如果放不下就走cas。
3:初始化:给变量赋上默认值。类加载的时候会给静态变量赋上默认值。
4:设置对象头:
image-20230226145734134
对象头里边主要包含Mark Word结构(中间那个图32位的)
正常的对象,没有加锁的对象就是无锁态那一行,前25保存hashCode,后4为保存分代年龄<=15,后边3位保存锁的状态。
Klass Pointer类型指针,一个对象new出来是在堆中,在这个对象头部区域有根指针指向元空间的类元信息,就是这个类型指针。比如 getClass,getMethod,getFileds… ….是通过这根指针找到的。
如果数组的话,会多出一块,存放数组长度占4个字节,只有数组才会有。
通过ClassLayout.parseInstance查看对象头
public static void main(String[] args) { System.out.println("Object --- "); ClassLayout layout = ClassLayout.parseInstance(new Object()); System.out.println(layout.toPrintable()); System.out.println("数组 --- "); ClassLayout layout1 = ClassLayout.parseInstance(new int[]{}); System.out.println(layout1.toPrintable()); System.out.println("B对象 --- "); ClassLayout layout2 = ClassLayout.parseInstance(new B()); System.out.println(layout2.toPrintable());}static class B { int id; String name; byte aByte; Object o;}
输出结果为:
Object --- java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243) 12 4 (loss due to the next object alignment)Instance size: 16 bytesSpace losses: 0 bytes internal + 4 bytes external = 4 bytes total数组 --- [I object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363) 12 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 16 0 int [I.<elements> N/AInstance size: 16 bytesSpace losses: 0 bytes internal + 0 bytes external = 0 bytes totalB对象 --- com.example.JvmModel.JvmTest$B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 65 cc 00 f8 (01100101 11001100 00000000 11111000) (-134165403) 12 4 int B.id 0 16 1 byte B.aByte 0 17 3 (alignment/padding gap) 20 4 java.lang.String B.name null 24 4 java.lang.Object B.o null 28 4 (loss due to the next object alignment)Instance size: 32 bytesSpace losses: 3 bytes internal + 4 bytes external = 7 bytes totalProcess finished with exit code 0
Instance size:为我们对象的大小。OFFSET:偏移量。SIZE:大小
我这电脑是64位,
Object内存:
前两行是Mark down 。
第三行是Klass Point,这是开启对象指针压缩,默认开启。没有开启的话,会由8个字节组成。。
最后一行是对齐。八个字节对齐,8的整数倍。是我们对象寻址效率最优的方式。
一个Object其实大小为12字节,但是为了要对齐8的整数倍,扩充4个字节,一个Object的大小为16个字节。
数组内存:
前两行依然是Mark down。
第三行是Klass Point。
第四行是数组的长度。
他的内存大小是16个字节,它不需要对齐。
B对象:
前三行… … markdown Klass Point
B.id:int占4个字节。
B.aByte:byte,占用一个字节。它的下一行是内存对齐,对齐成为4个字节。
B.name:String占用4个字节,存放的内存地址。这是开启对象指针压缩,默认开启。没有开启的话,会由8个字节组成。
B.o:对象占用4个字节,存放的内存地址。
最后一行对齐8。
5:执行init方法。将成员变量真正的赋值,然后还会调用对象的 构造方法。
标签: #java创建file对象