JVM内存模型学习小记

跨平台特性:软件层屏蔽底层指令差异。

JVM内存模型

JVM内存参数

元空间参数:

-XX:MetaspaceSize:原空间Full GC的初始阈值,默认21M;Full GC后收集器会调整该值,若释放大量空间,调小;若释放少量空间,调大。

建议:应用启动发生大量Full GC,通常是永久代或元空间发生了大小调整,一般设置MetaspaceSize = MaxMetaspaceSize > 初始值,对于8G物理内存,设置为256M。

-XX:MaxMetaspaceSize:元空间最大值,默认不限制(受限于本地内存大小)

JVM对象创建

1.类加载检查(是否已经加载类,否则先加载类)

2.分配内存:对象所需内存在类加载完成后便可确定。

--如何划分内存

----指针碰撞(默认使用)

----空闲列表

--并发分配

----CAS配上失败重试,分配内存空间动作原子性

----本地线程分配缓冲,内存分配按照线程划分在不同空间进行

3.初始化

4.设置对象头

HotSpot中,对象在内存中的存储布局:

--对象头

----存储对象自身运行时数据Mark Word(32位占4字节,64位占8字节)

------哈希码,GC分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等

----Klass Pointer类型指针(开启指针压缩4字节,不开启则占8字节)

------指向类元数据的指针,确定对象是哪个类的实例

----数组长度(4字节)

------只有数组对象才会有

--实例数据

--对齐填充(对象大小为8的整数倍,不足时需要填充)

5.执行方法,属性赋值(程序员赋值),执行构造方法

指针压缩

--使用较大指针在主内存和缓存之间移动数据,占用较大带宽,同时GC也会承受较大压力

--JVM中,32位地址最大支持4G,可以通过对对象指针压缩,编码解码进行优化,使得jvm使用32位地址就可以支持更大的内存配置(不超过32G)

----堆内存小于4G时,不需要启用指针压缩,jvm会直接去除高32位,使用低虚拟地址空间

----堆内存大于32G时,指针压缩失效,出现A问题,所以堆内存不要大于32G为好

对象内存分配

--对象栈上分配:jvm通过逃逸分析确定对象不会被外部访问,将对象在栈上分配,对象随栈帧出栈而销毁,减轻垃圾回收压力

----对象逃逸分析:分析对象动态作用域,会不会被外部方法引用。

----标量替换:通过逃逸分析确定对象不会被外部访问,并且对象可以进一步分解时,JVM不会创建对象,而是将对象成员变量分解若干个被这个方法使用的成员变量代替,这些代替的成员变量在栈帧或寄存器上分配空间。

----标量和聚合量:标量就是不可被进一步分解的量,java基本数据类型都是标量;聚合量就是可以被进一步分解的量,比如java中的对象。

对象栈上分配依赖于逃逸分析和标量替换。

对象Eden区分配

对象在新生代Eden区分配,当Eden区没有足够空间进行分配时,触发一次Minor GC

--Minor GC/Yong GC:新生代垃圾收集。频繁,速度快。

--Major GC/Full GC:老年代,年轻代,方法区一起垃圾收集。速度慢。

--Eden和Suvivor默认8:1:1

大对象直接进入老年代

--为了避免大对象分配内存时的复制操作而降低效率

----大对象:需要大量连续内存空间的对象(比如字符串,数组),JVM参数可设置大对象大小。(只在Serial和Parnew收集器下有效)

长期存活的对象进入老年代

--第一次Minor GC后仍能存活,并且能被Suvivor容纳,移动到Suvivor中,将对象年龄设为1;这样反复当年龄增加到15(CMS默认6),将对象移入老年代中。JVM参数可调整年龄。

对象动态年龄判断

--希望将可能是长期存活的对象,尽早进入老年代。

--一般在Minor GC之后触发,Suvivor中一批对象总大小大于Suvivor容量的50%,此时大于等于这批对象年龄最大值的对象就可以直接进入老年代。

老年代空间分配担保机制

年轻代每次 minor gc 之前JVM都会计算下老年代 剩余可用空间
如果这个可用空间小于年轻代里现有的所有对象大小之和( 包括垃圾对象 )
就会看一个“
-XX:-HandlePromotionFailure”(jdk1.8默认就设置了)的参数是否设置了
如果有这个参数,就会看看老年代的可用内存大小,是否大于之前每一次minor gc后进入老年代的对象的 平均大小
如果上一步结果是小于或者之前说的参数没有设置,那么就会触发一次Full gc,对老年代和年轻代一起回收一次垃圾,
如果回收完还是没有足够空间存放新的对象就会发生"OOM"
当然,如果minor gc之后剩余存活的需要挪动到老年代的对象大小还是大于老年代可用空间,那么也会触发full gc,full
gc完之后如果还是没有空间放minor gc之后的存活对象,则也会发生“OOM”

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JVMJava虚拟机)模型是指Java程序在运行时的执行环境,包括JVM的组成部分和它们的工作原理。JVM内存模型是指Java虚拟机管理程序运行时内存的方式,包括内存划分、内存分配和对象回收等机制。 JVM模型的组成部分包括类加载器、解释器、即时编译器、垃圾收集器等。类加载器负责将Java类加载到JVM中,并将其转换为可执行代码;解释器负责解释字节码并执行相应的指令;即时编译器则将频繁执行的代码编译成本地机器码,以提高程序的执行效率;垃圾收集器则负责回收程序运行时不再使用的内存JVM内存模型规定了Java程序运行时内存的分配和管理方式。JVM内存模型内存划分为不同的区域,包括方法区、堆、虚拟机栈、本地方法栈和程序计数器。其中,堆是Java程序运行时内存中最大的区域,用于存储对象实例。虚拟机栈和本地方法栈则用于存储程序执行时的局部变量和方法调用信息。方法区用于存储已加载的类信息、常量池、静态变量等数据。程序计数器则用于记录当前线程所执行的字节码指令位置。 JVM内存模型还包括垃圾回收机制,用于自动回收程序运行时不再使用的内存。垃圾回收机制采用标记-清除、复制、标记-整理等不同的算法来回收内存。 总之,JVM模型和JVM内存模型Java程序运行时的重要组成部分,了解和掌握它们的工作原理对于编写高效、稳定的Java程序至关重要。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值