jvm--指针压缩

2 篇文章 0 订阅

基础知识:
1字节=8个二进制位
64位计算机中48位用于内存存储,16位作为保留位;
32位机最大内存空间2的32次方=4G,64位机最大内存空间2的48次方=256T。

对象的内存模型:对象头,实例数据,对象填充
普通对象的对象内存模型 数组对象(未开启指针压缩)

对象头:
Mark Word:锁状态
类型指针:基于哪个类生成的对象;
数组长度:当对象是数组时,其长度信息存储;
实例数据:
类中定义的属性
对其填充:
以8字节对齐,不足的话以8字节或其整数倍补充对齐。

关闭指针压缩:-XX:-UseCompressedOops
开启指针压缩:-XX:+UseCompressedOops

【空对象】

package com.kyle.springbase.jvm;
import org.openjdk.jol.info.ClassLayout;
/**
* @author kyle
* @title: MyEmptyObject
* @projectName springbase
* @description: 空对象,检验占用内存大小
* @date 2021/4/11 14:12
*/
public class MyEmptyObject {
    /**
     * 需要引入包,查看内存占用大小
     * <!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
     * <dependency>
     *     <groupId>org.openjdk.jol</groupId>
     *     <artifactId>jol-core</artifactId>
     *     <version>0.15</version>
     *     <scope>provided</scope>
     * </dependency>
     *
     */

    public static void main(String[] args) {
        MyEmptyObject myEmptyObject = new MyEmptyObject();
        System.out.println(ClassLayout.parseInstance(myEmptyObject).toPrintable());
    }
}

未开启指针压缩:-XX:-UseCompressedOops

com.kyle.springbase.jvm.MyEmptyObject object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8        (object header: class)    0x00000000183b3028
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

开启指针压缩
在VM中开启:-XX:+UseCompressedOops

com.kyle.springbase.jvm.MyEmptyObject object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4        (object header: class)    0x2000c105
 12   4        (object alignment gap)    
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

Ps:
Mark Word 区大小不随指针压缩是否开启改变大小
类型指针区大小(KClass Pointer):开启指针压缩占用4B,不开启占用8B
对象对齐:不足8B倍数,要补齐

空对象(没有普通属性)占用多大空间?
1、未开启指针压缩:16字节 = 8B(Mark Word区) +8B
2、开启指针压缩:16字节 = 8B + 4B + 0 + 4B

【有属性的对象】

package com.kyle.springbase.jvm;

import org.openjdk.jol.info.ClassLayout;
/**
* @author kyle
* @title: MyNotEmptyObject
* @projectName springbase
* @description: 有属性的对象
* @date 2021/4/11 14:28
*/
public class MyNotEmptyObject {
    int a =1;
    int b = 2;
    double c = 3.0d;
    public static void main(String[] args) {
        MyNotEmptyObject myNotEmptyObject = new MyNotEmptyObject();
        System.out.println(ClassLayout.parseInstance(myNotEmptyObject).toPrintable());
    }
}

开启指针压缩:

com.kyle.springbase.jvm.MyNotEmptyObject object internals:
OFF  SZ     TYPE DESCRIPTION               VALUE
  0   8          (object header: mark)     0x0000000000000001 (non-biasable; age: 0)  //Mark Word
  8   4          (object header: class)    0x2000c105 // KClass Pointer
 12   4      int MyNotEmptyObject.a        1
 16   8   double MyNotEmptyObject.c        3.0
 24   4      int MyNotEmptyObject.b        2
 28   4          (object alignment gap)    // 对象填充
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

32B = 8B + 4B + 4B + 8B + 4B + 4B

关闭指针压缩:

com.kyle.springbase.jvm.MyNotEmptyObject object internals:
OFF  SZ     TYPE DESCRIPTION               VALUE
  0   8          (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8          (object header: class)    0x0000000017e53028
16   8   double MyNotEmptyObject.c        3.0
24   4      int MyNotEmptyObject.a        1
28   4      int MyNotEmptyObject.b        2
Instance size: 32 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

【数组对象】

package com.kyle.springbase.jvm;
import org.openjdk.jol.info.ClassLayout;
/**
* @author kyle
* @title: MyArrayObject
* @projectName springbase
* @description: 数组对象和普通对象的内存占用
* @date 2021/4/11 14:41
*/
public class MyArrayObject {
    int a = 1;
    int b = 2;
    static int[] c = {0, 1, 2};
    public static void main(String[] args) {
        MyArrayObject myArrayObject = new MyArrayObject();
        System.out.println(ClassLayout.parseInstance(c).toPrintable());
        System.out.println(ClassLayout.parseInstance(myArrayObject).toPrintable());
    }
}

未开启指针压缩:-XX:-UseCompressedOops

[I object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8        (object header: class)    0x0000000017920b68
16   4        (array length)            3
16   8        (alignment/padding gap)   //头部的填充
24  12    int [I.<elements>             N/A
36   4        (object alignment gap)    //对其填充
Instance size: 40 bytes
Space losses: 8 bytes internal + 4 bytes external = 12 bytes total


com.kyle.springbase.jvm.MyArrayObject object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   8        (object header: class)    0x0000000017d23080
16   4    int MyArrayObject.a           1
20   4    int MyArrayObject.b           2
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

开启指针压缩:-XX:+UseCompressedOops

[I object internals: //数组对象的内存占用
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)   //Mark Word
  8   4        (object header: class)    0x2000016d // KClass pointer
12   4        (array length)            3
12   4        (alignment/padding gap)   
16  12    int [I.<elements>             N/A
28   4        (object alignment gap)    
Instance size: 32 bytes
Space losses: 4 bytes internal + 4 bytes external = 8 bytes total

com.kyle.springbase.jvm.MyArrayObject object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)  //Mark Word
  8   4        (object header: class)    0x2000c105  //Mark Word
12   4    int MyArrayObject.a           1  //int 类型占用
16   4    int MyArrayObject.b           2  //int 类型占用
20   4        (object alignment gap)    // 对象补齐
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

oop:对象指针
jdk中,所有的对象都是以8字节对齐的(1000),所以后三位永远为0,开启指针压缩,就是将oop后面的三个0去掉,使用的时候内存地址后三位补0;

开启指针压缩,指针占用4个字节,然后加上这里去掉的3个位,那么oop最大空间为32+3=35位

开启指针压缩的情况下,如何扩容oop的最大空间?
在后面加0补齐,扩容到2^36

栈溢出的几种方式:
1、调用链太长;
2、死循环;
3、无限递归。

查看栈内存大小: java -XX:+PringFlagsFinal -version grep ThreadStack
栈的最小空间为:160K
如果栈的深度为772,如何计算栈的大小? 160K*1024/772

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值