🏆【JVM技术专区】「难点-核心-遗漏」TLAB内存分配+锁的碰撞(技术串烧)!
JVM内存分配及申请过程
当使用new关键字或者其他任何方式进行创建一个类的对象时,JVM虚拟机需要为该对象分配内存空间,而对象的大小在类加载完成后已经确定了,所以分配内存只需要在Java堆中划分出一块大小相等的内存,JVM虚拟机中有指针碰撞和空闲列表两种方式分配内存。
指针碰撞方式
如果Java堆中内存是规整排列的,所有被用过的内存放一边,空闲的可用内存放一边,中间放置一个指针作为它们的分界点,在需要为新生对象分配内存的时候,只要将指针向空闲内存那边挪动一段与对象大小相等的距离即可分配。
代表GC回收器
ParNew,Serial,G1
空闲列表方式
如果Java堆中内存不是规整排列的,用过的内存和可用内存是相互交错的,这种情况下将不能使用指针碰撞方式分配内存,Java虚拟机需要维护一个列表用于记录哪些内存是可用的,在为新生对象分配内存的时候,在列表中寻找一块足够大的内存分配,并更新列表上的记录。
代表GC回收器
cms
Java虚拟机选择策略
Java虚拟机采用哪种方式为新生对象分配内存,取决于所使用的垃圾收集器,当垃圾收集器具有整理过程时,虚拟机将采用指针碰撞的方式;当垃圾收集器的回收过程没有整理过程时,则采用空闲列表方式。
现在虚拟机栈进行分配
此部分属于两部分的分配机制,当JVM创建线程Thread对象:
直接分配:局部变量、形式参数表。
优化分配:逃逸分析(栈上分配、标量替换等功能)。
如果完成分配之后,则结束内存分配,否则出现分配失败,或者无法进行分配操作后,会进入堆内存方式的分配。
新生区-Eden区的分配
TLAB内存的分配策略
上面刚刚说过了,主要有两种内存分配机制:如果采用指针碰撞法,则会出现性能问题和指针分配冲突的问题.,JVM虚拟机采用优化的手段,就是TLAB(ThreadLocal Allocation Buffer)预先分配了内存块。
总体内存分配流程策略
如果TLAB内存分配失败或者空间不足,则JVM会试图为相关Java对象在Eden中初始化一块内存区域,当Eden空间足够时,内存申请结束
当如果出现了Eden区内存无法进行分配,则会发生相关MinorGC(JVM试图释放在Eden中所有不活跃的对象(Minor GC),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区)。
此时Survivor区被用来作为Eden及old的中间交换区域,如果Survivor不足以放置eden区的对象 ,会进行担保分配,或者已经达到直接晋升到老年代的条件后,此时如果old区有空闲,Survivor区的对象会被移到Old区。
当old区空间不够时,JVM会在old区进行major collection;
完全垃圾收集后,若Survivor及old区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现"Out of memory错误";
- jvm优先分配在eden区
- 当Eden空间足够时,内存申请结束。
JVM锁的膨胀执行流程机制
无锁节点/偏向锁阶段
创建线程的时候在程序执行到同步代码块的时候,首先会基于上面说到的内存分配策略进行分配内存,此时会当当前线程获取到了相关锁资源的时候,因为属于无锁状态下转换为偏向锁:
无锁标记头
偏向锁标记头
- 会将相关的当前线程的线程ID赋值到相关的标记字段中。
- 为了提高性能以及栈空间可以获取相关的竞争数据,会将对象头的标记字段(Markword)拷贝到栈空间内部(Lock Record)锁记录。
轻量级锁阶段
竞争到锁的线程
与此同时,当另外一个线程同时也去竞争该资源的时候,需要进行竞争,因为在获取资源的时候,底层采用CAS机制取获取相关的资源标志,一旦获取成功,便可以通过偏向锁标识进行判断是否属于当前的锁owner线程。
当发现不属于偏向锁的线程进来竞争的时候,此时会产生竞争关系,因为同一时刻,只能允许一个线程获取资源,当前获取资源的线程会因为有其他线程也争抢过该资源,故此将java对象头中的锁字段改为00,如下图所示:
未竞争到锁的线程
当发生线程争抢CAS机制失败的时候,会进行相关的自旋机制,进行尝试下一次进行争抢到锁。
重量级锁阶段
未竞争到锁的线程
当超过自旋的线程一直处于自旋,且超过了自旋阈值之后,变会升级成为了重量级锁。
或当更多的线程都处于争抢状态且属于自旋锁机制之后(出现了大量的轻量级锁之后),便会升级未重量级锁。
直到被唤醒重新镜像竞争锁资源信息。
升级为重量级锁的结果会将线程的标志位置为10
此时不会在进行自旋CAS争抢 ,而是直接阻塞执行(采用底层mutex/Fast Mutex锁进行暂停中断线程的执行)。
竞争到锁的线程
当锁标记因为发生变化,成为了重量级锁,所以,线程会同步自己的所记录,发现不一致,同步为重量级锁状态后,释放锁之后,进行唤醒阻塞的状态的线程。
锁的状态暂时处于重量级锁状态。接下来会专门写一篇文章讲解一下锁降级哦,锁降级会较为复杂,而且场景完全不一样,对JVM要求也不一样。
当对象出现消亡了回收状态:
🏆【JVM技术专区】「难点-核心-遗漏」TLAB内存分配+锁的碰撞(技术串烧)!的更多相关文章
- ☕【Java技术指南】「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!
前提介绍 本章主要介绍相关线程声明周期的转换机制以及声明周期的流转关系以及相关AQS的实现和相关的基本原理,配合这相关官方文档的中英文互译的介绍. 线程状态流转及生命周期 当线程被创建并启动以后,它既 ...
- JVM基础学习(二):内存分配策略与垃圾收集技术
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来 垃圾收集概述 Java内存模型中的堆和方法区是垃圾收集技术所需要关注的终点,因为其他的区域会跟 ...
- JVM学习笔记-第三章-垃圾收集器与内存分配策略
JVM学习笔记-第三章-垃圾收集器与内存分配策略 tips:对于3.4之前的章节可见博客:https://blog.csdn.net/sanhewuyang/article/details/95380 ...
- 【Java技术专题】「性能优化系列」针对Java对象压缩及序列化技术的探索之路
序列化和反序列化 序列化就是指把对象转换为字节码: 对象传递和保存时,保证对象的完整性和可传递性.把对象转换为有字节码,以便在网络上传输或保存在本地文件中: 反序列化就是指把字节码恢复为对象: 根据字 ...
- C++_类和动态内存分配6-复习各种技术及队列模拟
知识点: 队列:是一种抽象的数据类型(Abstract Data Type),可以存储有序的项目序列. 新项目被添加在队尾,并可以删除队首的项目.队列有些像栈.栈是在同一端进行添加和删除.这使得栈是一 ...
- LIbreOJ #6011. 「网络流 24 题」运输问题 最小费用最大流
#6011. 「网络流 24 题」运输问题 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- loj #547. 「LibreOJ β Round #7」匹配字符串
#547. 「LibreOJ β Round #7」匹配字符串 题目描述 对于一个 01 串(即由字符 0 和 1 组成的字符串)sss,我们称 sss 合法,当且仅当串 sss 的任意一个长度为 ...
- 一夜搞懂 | JVM GC&内存分配
前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习GC&内存分配? 时代发展到现在,如今的内存动态分配与内存回收技术已经相当成 ...
- jvm系列 (二) ---垃圾收集器与内存分配策略
垃圾收集器与内存分配策略 前言:本文基于<深入java虚拟机>再加上个人的理解以及其他相关资料,对内容进行整理浓缩总结.本文中的图来自网络,感谢图的作者.如果有不正确的地方,欢迎指出. 目 ...
随机推荐
- OpenFaaS实战之二:函数入门
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 如何访问网络损伤仪WANsim的控制界面
一台全新的WANsim网络损伤仪的默认IP地址为192.168.1.199.网络损伤仪的控制界面部署在 8080 端口. 所以,我们在成功连接了WANsim之后,只需要在控制电脑上打开谷歌浏览器,访问 ...
- CF1032G Chattering
CF1032G Chattering 题意 思路 对于每一个位置,它转移的范围是确定的. 对于一段可以走到的区间,我们可以求出区间中所有点再能走到区间范围. 于是这个就可以倍增进行转移. 如何快速求出 ...
- jmeter测试流程整理
背景 整理jmeter脚本编写流程,注意事项,常用组件,常见问题. 参看链接:https://www.cnblogs.com/pwj2lgx/p/10282422.html 参看:processOn思 ...
- Java中lombok @Builder注解使用详解(十八)
Lombok大家都知道,在使用POJO过程中,它给我们带来了很多便利,省下大量写get.set方法.构造器.equal.toString方法的时间.除此之外,通过@Builder注解,lombok还可 ...
- ASM入网小助手卸载
目录 ASM小助手卸载 写在前的 卸载 解除U盘禁用 写在后的 ASM小助手卸载 写在前的 有些公司内网的上网认证是用的ASM小助手,不过有时候用自己电脑接入公司内网可能会主动下载到ASM入网小助手的 ...
- SignalR的客户端.NET Client介绍
SignalR支持两种客户端:JavaScript Client和.NET Client.一个简单的SignalR例子中的SignalRDemo(点赞页面)就是JavaScript Client(HT ...
- GoldenEye-v1靶机
仅供个人娱乐 靶机信息 下载地址:https://pan.baidu.com/s/1dzs_qx-YwYHk-vanbUeIxQ 一.主机扫描 二.信息收集 三.漏洞的查找和利用 boris I ...
- vulnhub-DC:6靶机渗透记录
准备工作 在vulnhub官网下载DC:6靶机DC: 6 ~ VulnHub 导入到vmware,设置成NAT模式 打开kali准备进行渗透(ip:192.168.200.6) 信息收集 利用nmap ...
- 什么是软件的CLI安装
Websoft9 在进行开源软件的集成与自动化安装研究过程中发现有些软件有CLI安装模式,例如Gitlab CLI版本.Ghost CLI.PHP CLI等,CLI安装是什么意思? CLI(Comma ...