JVM:堆、方法区
一、堆
- 概念:堆用于存储对象和数组,主要分为新生代和老年代,新生代又细分为伊甸园区、幸存者 0 区(S0)和幸存者 1 区(S1)
- 内存设置:可用 -Xmx 和 -Xms 设置堆内存大小,-Xmx 为堆内存最大值,-Xms 是初始大小。若不设置,默认初始大小为物理内存的 1/64,最大为 1/4。超出最大内存,JVM 抛出内存溢出异常
- 新生代与老年代:新对象先存于伊甸园区,GC 后存活对象移至幸存者区,在 S0 和 S1 间移动。多次 GC 后仍存活的对象进入老年代。默认新生代与老年代大小比例为 1:2,可通过 -XX:NewRatio 调整。新生代中,伊甸园区和两个幸存者区默认比例为 8:1:1,可通过 -XX:SurvivorRatio 调整
- 对象分配:新对象(非大对象)先入伊甸园区,满后触发 Minor GC。首次 GC 时,伊甸园区存活对象移至 S0 或 S1 区,对象年龄加 1。后续每次 GC,存活对象在 S0 和 S1 间切换,默认对象年龄达 15 进入老年代。老年代满触发 Major GC(Full GC),若仍无法分配内存则抛出异常
- GC 分类:Minor GC 回收新生代;Major GC 主要回收老年代,实际中常伴随 Full GC;Full GC 会回收整个堆,包括新生代和老年代
- 分代目的:分代是为优化 GC 效率,有针对性回收,避免全堆回收耗时过长。多数对象在伊甸园区分配,大对象直接进入老年代
- TLAB:JVM 为每个线程在伊甸园区分配 TLAB,避免多线程对象分配时的竞争问题,保证线程安全。若 TLAB 空间不足,线程会加锁获取伊甸园区空闲区域以扩容
二、方法区
- 方法区是所有线程共享的。自 Java 8 开始,元空间成为其一种实现,它使用本地内存,不再受 JVM 堆内存限制,但仍受 JVM 管理
- Java 8 及以后,可通过 -XX:MetaspaceSize(初始默认大小)和 -XX:MaxMetaspaceSize(最大大小)设置其大小,超出最大大小会抛出内存溢出异常
- 内部结构:包含类信息(类的定义,如属性、方法定义及方法字节码,还有类的继承关系)、静态变量、运行时常量池(存放类中的常量、符号引用等)、JIT 即时编译器编译后的代码缓存
- GC 时方法区垃圾会被回收。常量无引用时会被回收;类需同时满足三个条件才会被回收:该类所有实例被销毁、该类的 java.lang.Class 对象未被引用、加载该类的类加载器已被回收
三、其它相关知识
(1)TLAB(Thread Local Allocation Buffer)
- 堆内存对象分配的线程安全问题:在多线程环境下,如果多个线程同时在堆的 Eden 区进行对象分配,可能会出现线程安全问题。因为堆是线程共享的内存区域,当多个线程同时尝试修改 Eden 区的空闲内存指针时,就可能导致数据不一致。例如,线程 A 和线程 B 同时读取到空闲内存指针指向地址 X,线程 A 在该地址创建了一个对象,然后将空闲内存指针向后移动;但线程 B 并不知道指针已经移动,仍然在地址 X 处创建对象,这就会造成内存覆盖和数据混乱
- TLAB 避免线程安全问题的原理:
- 线程私有缓存区域:TLAB 是在 Eden 区内为每个线程单独分配的一块私有缓存区域。每个线程在自己的 TLAB 中进行对象分配,就好像每个线程都有自己的 “专属领地”。由于 TLAB 是线程私有的,一个线程对其 TLAB 内的内存操作不会影响其他线程的 TLAB,因此避免了多个线程同时访问和修改同一内存区域的情况,从根本上解决了线程安全问题
- 减少锁竞争:如果没有 TLAB,线程在堆上分配对象时可能需要加锁来保证线程安全,频繁的加锁和解锁操作会带来较大的性能开销。而使用 TLAB 后,线程在自己的 TLAB 内分配对象无需加锁,只有当 TLAB 空间不足需要重新分配 TLAB 时,才需要同步锁定 Eden 区以获取新的 TLAB 空间,大大减少了锁竞争,提高了对象分配的效率
- 示例说明:假设有两个线程 Thread1 和 Thread2 同时运行,JVM 为它们分别分配了 TLAB1 和 TLAB2。当 Thread1 需要创建一个新对象时,它会直接在 TLAB1 中分配内存,不会影响 Thread2 的 TLAB2;同理,Thread2 在 TLAB2 中进行对象分配时也不会受到 Thread1 的干扰。只有当 TLAB1 或 TLAB2 空间不足时,线程才会去申请新的 TLAB 空间,并且在这个过程中会进行同步操作,以确保多个线程不会同时修改 Eden 区的空闲内存指针
(2)逃逸分析
3.2.1逃逸分析的概念
- 方法逃逸:一个对象在方法中被创建,但是它的引用被传递出了该方法,可能被其他方法使用。例如,在方法中创建对象并将其作为返回值返回,或者将对象的引用赋值给类的成员变量等
- 线程逃逸:一个对象的引用可以被多个线程访问到,比如将对象的引用存储在静态变量或者共享的集合中
3.2.2栈上分配
如果逃逸分析的结果表明一个对象不会发生逃逸,也就是该对象的引用不会超出当前方法的作用域,那么 JVM 可以选择将这个对象分配到栈上,而不是堆上
- 原理:栈上分配的对象会随着方法的结束而自动销毁,不需要垃圾回收器进行回收,这样可以减少堆内存的压力,也避免了垃圾回收带来的性能开销
- 示例:
public class StackAllocationExample {public static void main(String[] args) {for (int i = 0; i < 1000000; i++) {createObject();}}public static void createObject() {// 这里创建的对象未发生逃逸Point point = new Point(1, 2); } }class Point {private int x;private int y;public Point(int x, int y) {this.x = x;this.y = y;} }
在上述代码中,createObject 方法里创建的 Point 对象没有发生逃逸,JVM 就可能将其分配到栈上
3.2.3同步省略(锁消除)
当逃逸分析发现一个对象不会发生线程逃逸时,那么对该对象的同步操作(加锁)就可以被消除
- 原理:因为对象不会被其他线程访问,所以对它进行同步操作是没有必要的,JVM 会在编译时自动将这些不必要的同步代码去掉,从而减少了同步带来的性能开销
- 示例:
public class SyncEliminationDemo {public void test() {// 创建局部对象,不会发生线程逃逸Object lock = new Object();synchronized (lock) {System.out.println("执行同步块");}} }
在上述代码中,lock对象是test方法的局部变量,仅在该方法内使用,不会被其他线程访问。JVM 编译时,经逃逸分析确定lock无线程逃逸风险,会消除synchronized同步块,优化为:
public class SyncEliminationDemo {public void test() {Object lock = new Object();System.out.println("执行同步块");}
}
如此,避免了同步操作带来的性能开销,提升了程序执行效率
3.2.4标量替换
如果一个对象不会发生逃逸,JVM 可以不创建这个对象,而是将对象的成员变量分解成一个个独立的标量(基本数据类型)来代替
- 原理:将对象拆分成标量后,这些标量可以直接在栈上分配和操作,避免了对象创建和访问的开销,进一步提高了性能
- 示例:
public class ScalarReplacementExample {public static void main(String[] args) {alloc();}public static void alloc() {// 这里的 Point 对象可能会被进行标量替换Point point = new Point(1, 2); int x = point.x;int y = point.y;System.out.println(x + y);} }class Point {int x;int y;public Point(int x, int y) {this.x = x;this.y = y;} }
在 alloc 方法中,Point 对象没有发生逃逸,JVM 可能会将 Point 对象拆分成 x 和 y 两个标量,直接在栈上分配和使用
相关文章:
JVM:堆、方法区
一、堆 概念:堆用于存储对象和数组,主要分为新生代和老年代,新生代又细分为伊甸园区、幸存者 0 区(S0)和幸存者 1 区(S1)内存设置:可用 -Xmx 和 -Xms 设置堆内存大小,-X…...
JVM-基于Hotspot
前言 Java虚拟机(Java Virtual Machine简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,其主要任务为将字节码装载到内部,解释/编译为对应平台上的机器指令执行。 Java虚拟机规范定义了一个抽象的——…...
Android 10.0 第三方Launcher设置默认Launcher后导致Recent最近任务键无效
1.前言 在10.0的系统rom定制化开发中,在进入launcher的定制过程中,在某些产品中,需要设置第三方launcher为默认Launcher功能, 所以在设置以后,会发现最近recent键无效,所以接下来需要分析相关流程来实现相关功能的实现 2.第三方Launcher设置默认Launcher后导致Recent最…...
状态模式详解与真实场景案例(Java实现)
模式定义 状态模式(State Pattern) 允许对象在其内部状态改变时改变它的行为,使对象看起来像是修改了它的类。属于行为型设计模式,核心思想是将状态抽象为独立对象,不同状态下行为封装在不同状态类中。 解决的问题 …...
uniapp-商城-26-vuex 使用流程
为了能在所有的页面都实现状态管理,我们按照前面讲的页面进行状态获取,然后再进行页面设置和布局,那就是重复工作,vuex 就会解决这样的问题,如同类、高度提炼的接口来帮助我们实现这些重复工作的管理。避免一直在造一样的轮子。 https://vuex.vuejs.org/zh/#%E4%BB%80%E4…...
科技快讯 | 智谱开源最新GLM模型系列;“AI 洗头店”现身广州;ChatGPT上线图库功能
智谱开源最新GLM模型系列,启用全球域名“Z.ai” 4月15日,智谱开源最新GLM模型系列,包括32B和9B尺寸,涵盖基座、推理、沉思三类模型,全部遵循MIT开源许可协议。推理模型GLM-Z1-32B-0414实测推理速度达200 tokens/秒&…...
LeetCode 2537.统计好子数组的数目:滑动窗口(双指针)
【LetMeFly】2537.统计好子数组的数目:滑动窗口(双指针) 力扣题目链接:https://leetcode.cn/problems/count-the-number-of-good-subarrays/ 给你一个整数数组 nums 和一个整数 k ,请你返回 nums 中 好 子数组的数目。 一个子数组 arr 如果…...
精益数据分析(1/126):从《精益数据分析》探寻数据驱动增长之道
精益数据分析(1/126):从《精益数据分析》探寻数据驱动增长之道 在当今数字化时代,数据无疑是企业发展的关键驱动力,对于竞争激烈的程序化广告行业更是如此。最近我在研读《精益数据分析》这本书,收获颇丰&…...
uniapp-商城-27-vuex 通用方法
1 概述 上节说了vuex 的基本使用方法,分析了基本的使用方法。 在使用中,常见使用,我们要针对状态,购物车,不同类事务的管理,如果按照上节课的通用方法,那么使用和维护是会很大的难度的。 所以这里就必须要进行处理,借助 modules 进行定义不同类事务的处理手段。便于…...
MetaLiveX:用AI重新定义直播互动的边界
“直播的核心价值,在于它能否让观众从‘旁观者’变为‘共創者’。”在近期一场数字技术峰会上,杜子程(Emma Zicheng Du)首次公开阐释了其团队研发的MetaLiveX平台核心理念。这一以AI为驱动的智能直播系统,正通过动态场景生成与情感化交互设计,重新定义虚拟社群的参与逻辑。目前…...
线程安全学习
1 什么是线程 线程是cpu调度的最小单位,在Linux 下 实现线程的方式为轻量级进程,复用进程的结构体,使用clone函数创建 2 线程安全 所谓线程安全,更确切的应该描述为内存安全 #include <stdio.h> #include <pthread.h…...
三层路由器,SSH远程登录访问路由器,通过telnet远程登录访问路由器(不安全),路由器的基本设置之多网络互联解决办法:单臂路由
三层路由器 默认路由器端口关闭:no shutdown (开启)需进入端口默认路由开启:无需 ip routing路由器充当网关,可以连接不同网络接口种类丰富,数量少 SSH远程登录访问路由器 记得设IP Would you like to e…...
分布式光伏电站运维难?Acrel-1000DP助力安全稳定运行
针对用户新能源接入后存在安全隐患、缺少有效监控、发电效率无法保证、收益计算困难、运行维护效率低等通点,提出的Acrel-1000DP分布式光伏监控系统平台,对整个用户电站全面监控,为用户实现降低能源使用成本、减轻变压器负载、余电上网&#…...
基于sherpa-onnx 安卓语音识别尝鲜
sherpa-onnx简介 Sherpa:是一个由 K2-FSA 团队 开发的 开源语音处理框架,旨在解决传统语音识别工具(如 Kaldi)在模型部署和跨平台适配中的复杂性问题。它通过整合现代深度学习技术和高效推理引擎,提供了从语音识别、合…...
利用 Python 和 AI 技术创作独特的图像艺术作品
1. 项目目标 生成艺术作品:利用 AI 模型(如 Stable Diffusion)生成具有艺术风格的图像。自定义风格:通过文本提示(prompt)控制图像的艺术风格(如赛博朋克、印象派、超现实主义等)。…...
Web自动化测试的详细流程和步骤
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 Web自动化测试是软件测试中非常重要的一种测试方法,它通过编写脚本来模拟人工操作网页,从而实现对Web应用程序进行自动化测试的过程。为了保…...
记录一个坑关于STM32 ARM Compiler Version
在用 Keil 进行 STM32 开发的时候,一开始下载,下载的 ARM 编译器是 Version6,他就不兼容老的代码,就很抽象。 所以必须要更换编译器。 可以去官网下载编译器 Downloads - Arm Developer ,也可以自己找资源哈ÿ…...
TCP实现多线程远程命令执行
1.上一篇篇代码改进 bind的绑定第一个是对象,其余的都是参数,传给一个类需要this指针,所以有&r 错误地方是智能指针的参数要加&,thread.name()要删除 2.介绍需要用到函数 popen函数 FILE *popen(const char *command, …...
【MySQL】索引特性
文章目录 👉没有索引可能会有什么问题👈👉认识磁盘👈前置知识MySQL 与磁盘磁盘定位扇区结论磁盘随机访问与连续访问MySQL 与磁盘交互基本单位 👉MySQL 的整体轮廓👈👉索引的理解👈建…...
红宝书第四十七讲:Node.js服务器框架解析:Express vs Koa 完全指南
红宝书第四十七讲:Node.js服务器框架解析:Express vs Koa 完全指南 资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲 一、框架定位:HTTP服务器的工具箱 共同功能: 快…...
SDK游戏盾ip可以破解吗
从技术实现和法律合规性角度,不建议也不应尝试破解SDK游戏盾的IP防护机制。以下是详细分析: 一、法律与道德风险 违法行为 破解游戏盾的IP防护属于非法侵入计算机信息系统或破坏网络安全的行为,可能…...
eBay东南亚爆单密码:72小时交付计划如何重构厦门仓+东南亚供应链?
2024年东南亚电商市场规模预计突破2340亿美元,年复合增长率达18%。eBay最新战略将厦门纳入海外仓核心节点,推出“72小时交付计划”,通过“仓配转”一体化链路,助力中国卖家实现东南亚市场订单履约率提升10%,退货成本降…...
大语言模型
1.当前有哪些主流AI方向 1.1大语言模型方向 OpenAI的GPT语言模型系列,o3等推理模型系列 综合能力强 anthrotic的claude系列,推理预测混合模型 代码能力强 DeepSeek的V系列,R1推理模型 …...
深入理解Java缓冲输入输出流:性能优化的核心武器
在Java应用程序的IO操作中,频繁的磁盘读写或网络传输往往是性能瓶颈的主要来源。JDK提供的缓冲流(Buffered Streams)通过内存缓冲机制,将零碎的IO操作转化为批量处理,成为提升IO效率的关键技术。本文将从设计原理、核心机制到实战技巧,全面解析缓冲流的技术细节。 一、缓…...
AI 对话高效输入指令攻略(一):了解AI对话指令
目录 引 一.认识 AI 对话中的指令基础 1.运行原理 2.智能体在 AI 对话中的关键角色与运行机制 3.智能体的核心任务 4.对不同指令的响应差异 5.针对不同指令类型的处理方式 6.智能体在底层逻辑中的运作 二.高效输入指令的底层逻辑 1.语义匹配逻辑 …...
AI大模型从0到1记录学习 数据结构和算法 day19
常用算法 查找算法 二分查找 算法原理 二分查找又称折半查找,适用于有序列表。其利用数据的有序性,每轮缩小一半搜索范围,直至找到目标元素或搜索区间为空为止。 代码实现 def binary_search(arr, target): left, right 0, len(arr) - 1 w…...
Python + Playwright:使用正则表达式增强自动化测试
Python + Playwright:使用正则表达式增强自动化测试 前言一、 为什么选择正则表达式?二、 Playwright 中集成正则表达式:途径与方法三、 实战应用:正则表达式解决典型测试难题场景 1:定位 ID 或 Class 包含动态部分的元素场景 2:验证包含可变数字或文本的提示信息场景 3:…...
构建用户友好的记账体验 - LedgerX交互设计与性能优化实践
构建用户友好的记账体验 - LedgerX交互设计与性能优化实践 发布日期: 2025-04-16 引言 在财务管理应用领域,技术实力固然重要,但最终决定用户留存的往往是日常使用体验。本文作为LedgerX技术博客的第二篇,将深入探讨我们如何通过精心的交互…...
AI赋能PLC(一):三菱FX-3U编程实战初级篇
前言 在工业自动化领域,三菱PLC以其高可靠性、灵活性和广泛的应用场景,成为众多工程师的首选控制设备。然而,传统的PLC编程往往需要深厚的专业知识和经验积累,开发周期长且调试复杂。随着人工智能技术的快速发展,利用…...
人工智能——梯度提升决策树算法
目录 摘要 14 梯度提升决策树 14.1 本章工作任务 14.2 本章技能目标 14.3 本章简介 14.4 编程实战 14.5 本章总结 14.6 本章作业 本章已完结! 摘要 本章实现的工作是:首先采用Python语言读取含有英语成绩、数学成绩以及学生所属类型的样本数据…...
智能家居适老化改造:让科技回归“无感服务”
在老龄化加速与科技飞速发展的当下,智能家居适老化改造成为提升老年人生活品质的关键举措。 理想的适老化智能家居,应实现 “无感服务”,即让老年人在无需刻意操作或复杂学习的情况下,自然、流畅地享受科技带来的便利,…...
2025年最新Web安全(面试题)
活动发起人小虚竹 想对你说: 这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!…...
【linux】命令收集
1. 系统信息 uname -m:显示处理器架构uname -r:显示内核版本arch:显示处理器架构cat /proc/cpuinfo:查看CPU信息cat /proc/meminfo:查看内存使用情况cat /proc/version:显示内核版本date:显示系…...
从零到一:网站设计新手如何快速上手?
从零到一:网站设计新手如何快速上手? 在当今数字化时代,网站已成为企业、个人展示信息、提供服务的重要窗口。对于想要涉足网站设计领域的新手而言,如何快速上手并掌握必要的技能成为首要任务。本文将从基础知识、软件工具、设计…...
API平台(API网关)的API安全保障机制
API安全保障机制是一个复杂而重要的任务,需要综合运用多种技术和策略来确保API的安全性和稳定性。 1.黑名单 将不合法的服务、API及终端加入平台黑名单,限制其访问。支持黑名单的列表展示,且可将内容从黑名单删除。按类型、内容搜索黑名单。…...
【软考】论devops在企业信息系统开发中的应用
摘要: 随着互联网的不断发展,各行各业都在建设自己的企业信息系统,而随着业务的不断升级和复杂化,系统的更新迭代速度越来越快,系统也越来越复杂。对于信息系统开发者,架构师,管理者,…...
端、管、云一体化原生安全架构 告别外挂式防护!
面对数字化转型浪潮,企业网络安全风险日益凸显。数据泄露、黑客勒索等事件频发,合规要求加速推进。尽管企业纷纷部署了防病毒、身份认证、文件加密、入侵防护、流量监控等多种安全系统,但分散且孤立的架构非但没有有效抵御风险,反…...
每天记录一道Java面试题---day39
GC如何判断对象可以被回收了 回答重点 引用计数法: - 每个对象由一个引用计数属性,新增一个引用时计数器加1,引用释放时计数减1,计数为0时可以回收。可达性分析法: - 从GC Roots开始向下搜索,搜索所走过的…...
码界奇缘 Java 觉醒 后记 第二十五章 安全结界攻防战 - 从沙箱到模块化
第二十五章:安全结界攻防战 - 从沙箱到模块化 知识具象化场景 陆小柒站在由安全策略文件堆砌的古城墙上,眼前是千疮百孔的沙箱结界。空中漂浮着残缺的SecurityManager符石,远处java.security包化身的青铜守卫正在崩塌: 权限校验…...
【数据结构】励志大厂版·初阶(复习+刷题):线性表(顺序表)
前引:上一篇我们复习了复杂度,今天我们来通过实践回忆我们的线性表知识点,下面将讲解什么是线性表,顺序结构又是什么,知识点简洁精髓,无废话可言,小编会从每个细节讲起,包含头文件的…...
C 语言结构体中的函数指针与 Kotlin 高阶函数的对比
在学习 C 语言的过程中,很多 Java/Kotlin 背景的开发者都会对结构体中出现的“函数指针”感到陌生。特别是当看到如下代码时: struct Animal {void (*speak)(void); };void dogSpeak() {printf("Woof!\n"); }int main() {struct Animal dog;d…...
MicroK8s和K8s的区别优劣在哪?
运行ubuntu24.04后提示这么一段话: Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8sjust raised the bar for easy, resilient and secure K8s cluster deployment.https://ubuntu.com/engage/secure-kubernetes-at-the-edge 这段话…...
C++指针和引用之区别(The Difference between C++Pointers and References)
面试题:C指针和引用有什么区 C指针和引用有什么区别? 在 C 中,指针和引用都是用来访问其他变量的值的方式,但它们之间存在一些重要的区别。了解这些区别有助于更好地理解和使用这两种工具。 01 指针 指针(Pointer…...
Linux——Shell编程之正则表达式与文本处理器(笔记)
目录 基础正则表达式 1:基础正则表达式示例 (4)查找任意一个字符“.”与重新字符“*” (5)查找连续字符范围“{ }” 文本处理器 一、sed工具 二、awk工具 (1)按行输出文本 (2࿰…...
关于k8s的部署
一、实验目的 1、理解k8s的组件的功能; 2、理解k8s中的资源类型; 3、 熟练掌握k8s部署配置; 二、实验内容: 前置知识点: 写出k8s有哪些组件并简述作用? ①Master 组件: Master 组件提供集…...
营销自动化实战指南:如何用全渠道工作流引爆线索转化率?
在数字化浪潮席卷全球的今天,企业争夺用户注意力的战场已从单一渠道转向全渠道。然而,面对海量线索,许多团队依然深陷效率泥潭:人工处理耗时费力、高价值线索流失、跨渠道数据难以整合……如何破局?营销自动化正成为企…...
利用Global.asax在ASP.NET Web应用中实现功能
Global.asax文件(也称为ASP.NET应用程序文件)是ASP.NET Web应用程序中的一个重要文件,它允许您处理应用程序级别和会话级别的事件。下面介绍如何利用Global.asax来实现各种功能。 Global.asax基本结构 <% Application Language"C#&…...
【Linux 并发与竞争实验】
【Linux 并发与竞争实验】 之前学习了四种常用的处理并发和竞争的机制:原子操作、自旋锁、信号量和互斥体。本章我们就通过四个实验来学习如何在驱动中使用这四种机制。 文章目录 【Linux 并发与竞争实验】1.原子操作实验1.1 实验程序编写1.2 运行测试 2.自旋锁实验…...
数据一致性策略之延迟双删-实现
延迟双删 查询数据之前优先去查Redis的缓存数据,减少数据库压力; 如果没有缓存会去查数据库,通过查询数据库后缓存热点Key Cache-Aside策略 高并发场景时,严重生产bug:数据不一致 业务场景: 事务1&#x…...
在PyTorch中,使用不同模型的参数进行模型预热
在PyTorch中,使用不同模型的参数进行模型预热(Warmstarting)是一种常见的迁移学习和加速训练的策略。以下是结合多个参考资料总结的实现方法和注意事项: 1. 核心机制:load_state_dict()与strict参数 • 部分参数加载&…...