java int integer内存_天恩与天泽 / Java里int和integer的内存占用差别

在Java里,描述int和Integer的内存占用差别

想清楚描述这个问题,咱们先来聊聊Java内存

Java内存分为5个虚拟区域

421605275b9e250e123f72bec814d983.png

堆的概念大白话说就是new操作符申请的内存

堆内存线程共享

堆内存耗尽时,JVM抛出OOM异常

堆内存可以通过 -Xms -Xmx调整

堆内存Eden - 负责保存新对象或生命周期很短的,YoungGC主要是清理该区域

Survivor - YoungGC清理后,幸存下来的就在Survivor区

Old - YoungGC清理了好多好多次,依然能存活的对象,对象就会被转移到Old区。Old区的回收是依赖major GC进行

方法区PermGen - 永久保留区,也叫持久代。保存类定义、结构、字段、方法以及常量。注:PermGen在Java8已经被彻底删除了,取代他的另一个内存区域叫MetaSpace。

CodeCache - 主要保存编译后生成的字节码,包括Class和Meta的信息。注:运行常量池也是保存在该区域,静态。

栈空间每个线程独享栈内存。

主要存储局部变量、当前线程上下文、操作指令

本地栈全称应该是Native Method Stacks

从Java调用Native方法时,使用NativeStack

8ebd960848df76dec35007426f8dcd42.png

PC寄存器线程启动的时候会一个PC寄存器。

PC寄存器里面保存当前正在执行的JVM指令地址,如果是Native方法,这里是Undefined。

在当前命令执行前、执行中,PC寄存器保存的是当前指令地址。

在当前命令执行完,PC寄存器会保存下一个执行执行的地址。

Java对象的内存布局类加载检查JVM遇到一条new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类的加载过程ClassLoader。

对象头(Header)在32位系统上占用8bytes,在64位系统上占用16bytes

包括了MarkWord和KlassPointerMarkWord在32位系统上占用了4bytes,64位系统占用了8bytes,包括了哈希码、GC分代年龄、锁状态标志、线程持有锁、偏向线程ID、偏向时间戳

db3550b151b60b431c443fdf9a398f7d.pngKlassPointer:

类元数据指针,一个指向Metadata的类描述指针实例数据(Instance Data)原始类型 Primitive type 内存占用如下:Primitive TypeMemory Required(bytes)boolean1

byte1

short2

char2

int4

float4

long8

double8引用类型 Reference

32位系统上每个占用4bytes

64位系统上每个占用8bytes对齐填充(Padding)HotSpot的对齐方式为8个字节对齐

一个Object占用的内存大小

new Object() : Header 16

class A { int a; } : Header 16 + int 4 + padding 4 = 24

class A { Integer a; } : Header 16 + Reference 8 = 24

new Integer[1] : Header 24 + Refrence 8 = 32

int的内存占用

int a = 1;

在线程栈上申请8个字节空间,存放1的值,占用的是JvmStack内存

Integer的内存占用

Integer a = new Integer(1);

new Integer(1) : Header 16 + int 4 + padding 4 = 28字节堆内存

在线程上申请8个字节控件,存放new Integer对象堆地址

Jvm启动的时候内存占用Java程序的堆内存,最大就是 -Xmx设置的这个值

Garbage Collection在垃圾回收的时候使用的内存

JIT optimization使用的内存

Java程序的Off-heap所使用的内存

Java程序的Metaspace所使用的内存

JNI Code所占用的内存

Jvm启动的时候所占用的内存。

逃逸分析逃逸分析的基本行为就是分析对象的动态作用域:当一个对象在方法中被定义后,会发生 线程逃逸 或 方法逃逸

如果证明一个对象不会发生逃逸,则可能进行以下优化:栈上分配将该对象分配在栈上

同步消除消除线程安全锁

标量替换只用标量来替换对象,例如用int替换Integer

参考链接

stackoverflow:二叉查找数

备注

本文不讨论指针压缩 -XX:UseCompressedOops

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值