当前位置:首页 > 科技  > 软件

面试官问:Java中的new关键字做了什么事情?

来源: 责编: 时间:2024-03-28 17:51:14 112观看
导读各位小伙伴,当我们new一个对象的时候,对象到底是怎么生产出来的呢,我们这篇说一说对象生成的过程和内存的分配机制,面试的时候可以扯一扯,绝对是加分项。
图片1.加载类时检查
虚拟机在执行的过程中,执行到new关键字(new关键

各位小伙伴,当我们new一个对象的时候,对象到底是怎么生产出来的呢,我们这篇说一说对象生成的过程和内存的分配机制,面试的时候可以扯一扯,绝对是加分项。
dB228资讯网——每日最新资讯28at.com

图片图片dB228资讯网——每日最新资讯28at.com

1.加载类时检查
虚拟机在执行的过程中,执行到new关键字(new关键词、对象克隆、对象序列化等)的时候,第一步是先去检查这个指令的参数对应的符号引用是否在常量池中,其对应的类是否已经被加载解析和初始化,如果已经有,就代表此类已经被加载过了,如果吗,没有就说明类还没有被加载,那就要执行类记载的整个过程。dB228资讯网——每日最新资讯28at.com

2.内存的分配
在类加载过程完成后,就要对新创建的对象进行分配内存的操作,那么对应所需要的内存具体大小是如何确定的呢,其实对象所需内存的大小在类加载完成后就可以完全确定了,虚拟机只需要在java堆中划分出相应大小的固定的一块内存空间即可。
但是在分配内存这个过程中有两个问题:
1.如何划分内存。
2.在并发情况下, 可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。dB228资讯网——每日最新资讯28at.com

虚拟机有两种内存分配方法,一种是“指针碰撞”,一种是“空闲列表”,java默认采用的是指针碰撞,指针碰撞针对于规整的java堆,被使用的内存全都集中在堆的一边,而另一边都是空闲的内存,当需要分配固定大小的内存时候,只需要将内存的指针(分界点的指示器)从当前使用的位置向后挪动相应大小即可。当堆内存分配不是规整的时候,被使用的内存和没有被使用的内存交错相间,虚拟机很难找到一块固定大小且连续的内存空间,这时候指针碰撞就很难发挥出作用,这个时候虚拟机采用的是空闲列表,空闲列表是用来维护哪些内存块是空闲的,在进行分配内存的时候,只需要去空闲列表中找到一块大小合适且连续的内存块就可以了,然后再把这块内存空间在空闲列表上更新其记录。dB228资讯网——每日最新资讯28at.com

解决并发问题的方法:
CAS(compare and swap): 虚拟机采用CAS配上失败重试的方式保证更新操作的原子性来对分配内存空间的动作进行同步处理。dB228资讯网——每日最新资讯28at.com

本地线程分配缓冲(Thread Local Allocation Buffer,TLAB): 把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存。通过-XX:+/-UseTLAB参数来设定虚拟机是否使用TLAB(JVM会默认开启-XX:+UseTLAB),-XX:TLABSize 指定TLAB大小。dB228资讯网——每日最新资讯28at.com

3.初始化零值
内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头), 如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。dB228资讯网——每日最新资讯28at.com

4.设置对象头
初始化零值之后,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头Object Header之中。dB228资讯网——每日最新资讯28at.com

在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、 实例数据(Instance Data)和对齐填充(Padding)。HotSpot虚拟机的对象头包括两部分信息,第一部分用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时 间戳等。对象头的另外一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。dB228资讯网——每日最新资讯28at.com

32位对象头:dB228资讯网——每日最新资讯28at.com

图片图片dB228资讯网——每日最新资讯28at.com


dB228资讯网——每日最新资讯28at.com

64位对象头:dB228资讯网——每日最新资讯28at.com

图片图片dB228资讯网——每日最新资讯28at.com


dB228资讯网——每日最新资讯28at.com

5.执行方法
执行方法,即对象按照程序员的意愿进行初始化。对应到语言层面上讲,就是为属性赋值(注意,这与上面的赋零值不同,这是由程序员赋的值),和执行构造方法。dB228资讯网——每日最新资讯28at.com

对象大小与指针压缩
对象大小可以用jol-core包查看,引入依赖dB228资讯网——每日最新资讯28at.com

<dependency>    <groupId>org.openjdk.jol</groupId>    <artifactId>jol-core</artifactId>    <version>0.9</version></dependency>
import org.openjdk.jol.info.ClassLayout;/** * 计算对象大小 */public class JOLSample {    public static void main(String[] args) {        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();        ClassLayout layout2 = ClassLayout.parseInstance(new A());        System.out.println(layout2.toPrintable());    }    // -XX:+UseCompressedOops           默认开启的压缩所有指针    // -XX:+UseCompressedClassPointers  默认开启的压缩对象头里的类型指针Klass Pointer    // Oops : Ordinary Object Pointers    public static class A {                       //8B mark word                       //4B Klass Pointer   如果关闭压缩-XX:-UseCompressedClassPointers或-XX:-UseCompressedOops,则占用8B        int id;        //4B        String name;   //4B  如果关闭压缩-XX:-UseCompressedOops,则占用8B        byte b;        //1B         Object o;      //4B  如果关闭压缩-XX:-UseCompressedOops,则占用8B    }}运行结果:java.lang.Object object internals: OFFSET  SIZE   TYPE DESCRIPTION                               VALUE      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)    //mark word      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)    //mark word           8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)    //Klass Pointer     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 totalcom.tuling.jvm.JOLSample$A 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)                           61 cc 00 f8 (01100001 11001100 00000000 11111000) (-134165407)     12     4                int A.id                                      0     16     1               byte A.b                                       0     17     3                    (alignment/padding gap)                       20     4   java.lang.String A.name                                    null     24     4   java.lang.Object A.o                                       null     28     4                    (loss due to the next object alignment)Instance size: 32 bytesSpace losses: 3 bytes internal + 4 bytes external = 7 bytes total

什么是java对象的指针压缩?
1.jdk1.6 update14开始,在64bit操作系统中,JVM支持指针压缩
2.jvm配置参数:UseCompressedOops,compressed--压缩、oop(ordinary object pointer)--对象指针
3.启用指针压缩:-XX:+UseCompressedOops(默认开启),禁止指针压缩:-XX:-UseCompressedOopsdB228资讯网——每日最新资讯28at.com

为什么要进行指针压缩?
1.在64位平台的HotSpot中使用32位指针(实际存储用64位),内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据,占用较大宽带,同时GC也会承受较大压力dB228资讯网——每日最新资讯28at.com

2.为了减少64位平台下内存的消耗,启用指针压缩功能dB228资讯网——每日最新资讯28at.com

3.在jvm中,32位地址最大支持4G内存(2的32次方),可以通过对对象指针的存入堆内存时压缩编码、取出到cpu寄存器后解码方式进行优化(对象指针在堆中是32位,在寄存器中是35位,2的35次方=32G),使得jvm只用32位地址就可以支持更大的内存配置(小于等于32G)dB228资讯网——每日最新资讯28at.com

4.堆内存小于4G时,不需要启用指针压缩,jvm会直接去除高32位地址,即使用低虚拟地址空间dB228资讯网——每日最新资讯28at.com

5.堆内存大于32G时,压缩指针会失效,会强制使用64位(即8字节)来对java对象寻址,这就会出现1的问题,所以堆内存不要大于32G为好dB228资讯网——每日最新资讯28at.com

对象大小计算dB228资讯网——每日最新资讯28at.com

  1. 在32位系统下,存放Class指针的空间大小是4字节,MarkWord是4字节,对象头为8字节。
  2. 在64位系统下,存放Class指针的空间大小是8字节,MarkWord是8字节,对象头为16字节。
  3. 64位开启指针压缩的情况下,存放Class指针的空间大小是4字节,MarkWord是8字节,对象头为12字节。数组长度4字节+数组对象头8字节(对象引用4字节(未开启指针压缩的64位为8字节)+数组markword为4字节(64位未开启指针压缩的为8字节))+对齐4=16字节。
  4. 静态属性不算在对象大小内。


dB228资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-80197-0.html面试官问:Java中的new关键字做了什么事情?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 拿下阿里巴巴面试:10分钟了解JVM类加载过程?

下一篇: 面试官:说说Spring中IoC实现原理?

标签:
  • 热门焦点
  • 小米官宣:2023年上半年出货量中国第一!

    小米官宣:2023年上半年出货量中国第一!

    今日早间,小米电视官方微博带来消息,称2023年小米电视上半年出货量达到了中国第一,同时还表示小米电视的巨屏风暴即将开始。“公布一个好消息2023年#小米电视上半年出货量中国
  • vivo TWS Air开箱体验:真轻 臻好听

    vivo TWS Air开箱体验:真轻 臻好听

    在vivo S15系列新机的发布会上,vivo的最新款真无线蓝牙耳机vivo TWS Air也一同发布,本次就这款耳机新品给大家带来一个简单的分享。外包装盒上,vivo TWS Air保持了vivo自家产
  • 一篇文章带你了解 CSS 属性选择器

    一篇文章带你了解 CSS 属性选择器

    属性选择器对带有指定属性的 HTML 元素设置样式。可以为拥有指定属性的 HTML 元素设置样式,而不仅限于 class 和 id 属性。一、了解属性选择器CSS属性选择器提供了一种简单而
  • 腾讯盖楼,字节拆墙

    腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之&ldquo;想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!&rdquo;曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • 微博大门常打开,迎接海外画师漂洋东渡

    微博大门常打开,迎接海外画师漂洋东渡

    作者:互联网那些事&ldquo;起猛了,我能看得懂日语了&rdquo;。&ldquo;为什么日本人说话我能听懂?&rdquo;&ldquo;中文不像中文,日语不像日语,但是我竟然看懂了&rdquo;&hellip;&hell
  • 小米汽车电池信息疑似曝光:容量101kWh,支持800V高压快充

    小米汽车电池信息疑似曝光:容量101kWh,支持800V高压快充

    7月14日消息,今日一名博主在社交媒体发布了一张疑似小米汽车电池信息的照片,显示该电池包正是宁德时代麒麟电池,容量为101kWh,电压为726.7V,可以预测小
  • iQOO Neo8系列今日官宣:首发天玑9200+ 全球安卓最强芯!

    iQOO Neo8系列今日官宣:首发天玑9200+ 全球安卓最强芯!

    在昨日举行的的联发科新一代旗舰芯片天玑9200+的发布会上,iQOO官方也正式宣布,全新的iQOO Neo8系列新品将全球首发搭载这款当前性能最强大的移动平台
  • SN570 NVMe SSD固态硬盘 价格与性能兼具

    SN570 NVMe SSD固态硬盘 价格与性能兼具

    SN570 NVMe SSD固态硬盘是西部数据发布的最新一代WD Blue系列的固态硬盘,不仅闪存技术更为精进,性能也得到了进一步的跃升。WD Blue SN570 NVMe SSD的包装外
  • 苹果MacBook Pro 2021测试:仍不支持平滑滚动

    苹果MacBook Pro 2021测试:仍不支持平滑滚动

    据10月30日9to5 Mac 消息报道,苹果新的 14 英寸和 16 英寸 MacBook Pro 2021 上市后获得了不错的评价,亮点包括行业领先的性能,令人印象深刻的电池续航,精美丰
Top