小结
1:Java中创建对象的方式
1-1:new -通过调用构造器来初始化实例字段
1-2:反射-通过调用构造器来初始化实例字段
1-3:Object.clone-通过直接复制已有的数据,来初始化新建对象的实例字段
1-4:反序列化-通过直接复制已有的数据,来初始化新建对象的实例字段
1-5:Unsafe.allocateInstance-没有初始化对象的实例字段
2:Java对象的空间占用
2-1:通过new创建的对象,涵盖了它所有父类中的对象实例的字段
2-2:对象头,由标记字段和类型指针构成
2-3:标记字段,用于存储Java虚拟机有关该对象的运行数据,比如:哈希码、GC信息、锁信息等
2-4:类型指针,用于指向该对象的类
2-5:此对象的实例字段对应的内存空间
3:压缩指针
JVM的内存空间有限且昂贵,所以,能缩减的就缩减,通过一定的算法改进压缩类型指针的空间后仍可以寻址到对象的实例对应的类,所以,就采用了
4:字段重排
意思是JVM会重新分配字段的位置,和我们Java源码中属性声明的位置存在差异,猜想Java编译器编译后的字节码是没有改变源码中字段声明的位置的,这样做是为了更好的实现内存对齐,内存对齐本质上会浪费一定的内存空间,不过可以减少内存行的读取次数,通过一消一涨的比对发现这样对于JVM的性能有一定的提高,所以,也就使用了这种方式,浪费点空间能提高性能也是值得的
疑问❓
1:为什么一个子类即使无法访问父类的私有实例字段,或者子类实例字段隐藏了父类的同名实例字段,子类的实例还是会为这些父类实例字段分配内存呢?
另外,如果采用指针指向的方式定位父类实例的内容是否能更节省内存空间?
2:五种创建对象的方式,通过new指令新建出来的对象,他的内存其实涵盖了所有父类中的实例字段,其他的方式是怎样的哪?
展开