一图解千愁,JVM内存从来没有这么简单过

claude code desktop中出现Doesn‘t look like an Anthropic model - expected a gateway model route 解决方案 本文主要介绍了claude code desktop中出现Doesn’t look like an Anthropic model - expected a gateway model route referencing an Anthropic model和Server is busy. Retrying的解决方案,希望能对使用claude code desktop的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案 阅读详情

了解了这张图,会让你对JVM内存的划分有更深入的理解,而不仅限于什么虚拟机栈、程序计数器等比较浅显的认知。

那么这张图有什么用呢?在进行内存排查的时候,我们需要了解到底是哪一个部分出了问题。如果你找不对地方,肯定切入就比较困难,这会耗费你大量的精力。

一台4GB的机器,一般使用Xmx分配给JVM的,肯定不能太多。比如3.5GB之类的。这就太贪婪了,很容易造成JVM异常死亡。这是为什么呢?

这个比较好理解,因为在操作系统上,运行的不仅仅你的JVM应用,还会有其他一些守护进程,比如各种日志收集工具、监控工具、安全工具等。它们虽然占用的内存不是很多,但累加起来还是比较可观的。JVM内存和操作系统的剩余内存是一个此消彼长的关系,这些小内存挤占了JVM的发挥空间,就容易出问题。

JVM是我们的主体,所以要把它放在主人公的位置。这种划分方式,就可以把整个内存搞成JVM内存、操作系统物理内存、SWAP三个部分。

当JVM和其他程序占满了物理内存,接着占满了SWAP内存(交换分区一般不开,这个一会在说),当在需要申请内存空间的时候,操作系统发现: 完蛋了,没有可用的内存空间了。

这个时候,Linux会启动oom-killer,杀死占用内存最大的进程,这个时候大概率是你可爱的JVM宝贝进程。

这里的oom,指的是操作系统的,而不是JVM的。所以你会发现: 你的java进程死了,但是什么都没有留下。就这么静悄悄的去了。

这些信息,只能通过dmesg命令找到,属于操作系统范畴。

那么接下来,我们就上一下最主要的一张图,然后解释一下这十几部分都是干什么的。

我们依然把内存分为上面的三部分,但是对JVM的进程内存进行更细致的划分。

首先,对于JVM的内存,有堆内内存和堆外内存之分。

对于堆内内存,是我们平常打交道最多的地方,因为我们大部分Java对象,都是在堆上分配的。一旦有溢出问题,使用jmap + mat等一系列猛如虎的操作,就可以方便快捷的发现问题。

这是一个Java好手都能掌握的技能。

关键就是堆外内存那一部分,就十分的蛋疼了。因为杂七杂八的东西都在这里,很容易搞混。

可以看到,对于这部分的内存问题,即使是JVM界最权威的周老师的书籍,依然也有相关的错误。

这段代码的运行结果其实是错误的,这里的unsafe,并不是直接内存。

那我们就盘点一下里面都有些啥。

第一,元空间

元空间是jdk8以后才加入的,用来替换原来的永久代。也就是说,原perm区(永久代)中的方法区,也在这里。从它原来的名字就可以看出来,永久代指的就是那些变动很少的数据,稳定为主。比如我们在jvm启动时,加载的那些class文件;以及在运行时,动态生成的代理类。

比较坑的是,元空间的大小,默认是没有上限的。极端情况下,会一直挤占操作系统的剩余内存。

第二、CodeCache

很多文章对这一部分的介绍非常少,但其实这也是非常重要的一个非堆区域。因为JIT是JVM一个非常重要的特性,CodeCahe存放的,就是即时编译器所生成的二进制代码。当然,JNI的代码也是放在这里的。

这个空间在不同的平台,大小都是不一样的,但一般够用了。也有同学手贱把这个区域调的非常的小,这种情况下,JVM不会溢出,这个区域也不会溢出,但是会退化成解释型执行模式,速度和JIT不可同日而语,慢个数量级也是可能的。

本地内存

其实,在聊天的时候,我们相互谈到的堆外内存,大部分指的是这里,大部分出问题的,也是这里。它有更细致的划分。

(1)网络内存

网络连接也是要占用很多内存的。这个连接就非常有意思,你可以认为它是操作系统内核所占用的内存,也可以认为是JVM进程占用的内存。

如果你的系统并发非常高,这部分内存的占用也是比较多的。因为连接一般对应着网卡的数据缓冲区,还有文件句柄的耗费。

(2)线程内存

同样的,如果你造的线程非常多,JVM除了占用Thread对象本身很小的一部分堆内存,大部分是以轻量级进程的方式存在于操作系统。

这同样是一个积少成多的内存区域,但一般不会发生问题。

(3)JNI内存

上面谈到CodeCache存放的JNI代码,JNI内存就是指的这部分代码所malloc的具体内存。

比如Java的zip库,就不是在JVM的堆里完成的,而是开辟了一个堆外的缓冲池进行运算。

(4)直接内存

直接内存,指的是使用了Java的直接内存API,进行操作的内存。这部分内存可以受到JVM的管控,比如ByteBuffer类所做的事情。

ByteBuffer底层是用的unsafe,但unsafe是不受直接内存的管控的,它们不是一个东西。

上面提到的书中直接使用unsafe程序,并不会造成JVM直接内存溢出,反而会造成操作系统内存溢出。


那这些内存我们如何看待呢?

linux下有一个命令lsof,可以看到JVM进程所关联的所有句柄信息,一般可作为参考。

进一步,使用pmap函数,即可观测到具体的内存分布。但是不要怕,有很多是共享内存。

这个具体的过程,可以参见之前写的一篇堆外内存排查的文章。

如果你了解了图中这些内存划分,就会很容易了解,为什么NMT工具无法显示JNI内存的统计。

接下来,我们总结一下,这些内存区域,哪些参数能够控制它们。

  • 堆 -Xmx -Xms
  • 元空间 -XX:MaxMetaspaceSize -XX:MetaspaceSize
  • 栈 -Xss
  • 直接内存 -XX:MaxDirectMemorySize
  • JIT编译后代码存放 -XX:ReservedCodeCacheSize
  • 其他堆外内存 无法控制!随缘吧。

可以看到,堆外内存的占用,其实还是比较多的。如果你太贪婪,整个内存很容易就玩玩。

一般的,我们使用操作系统的2/3作为堆空间,是比较合理的。这是一个经验值。比如6GB的内存,你分配给JVM的,最好不要超过4GB。

还有,我们上面谈到的swap交换分区,在高并发应用中,一般是关掉的。因为它会造成频繁的页交换,在GC的时候,会引起严重的卡顿。

但要辩证的思维看待问题。对于低频的,对内存大小有非常大的依赖的情况下,SWAP不仅要开,还要开的大一些。

基于自适应小波阈值算法的图像去噪 自适应小波阈值算法是一种基于小波变换的方法,它相对于传统的小波阈值去噪方法具有更好的性能和鲁棒性。该算法首先对图像进行小波变换,然后根据小波系数的大小确定一个自适应的阈值,将小波系数与阈值进行比较,大于阈值的系数被保留,小于阈值的系数被置零。在上述代码中,首先选取了小波函数sym4进行小波分解,然后根据标准差计算出阈值,使用wthresh函数进行阈值处理,最后进行反变换得到处理后的图像。该GUI界面与前面的自适应小波阈值算法代码结合,实现了图像的去噪,并提供了可视化的效果。 阅读详情

相关推荐

基于pytest+Allure+Python+CANoe的汽车诊断自动化测试框架搭建实战

自动化测试是提升软件质量和研发效率的关键技术,其核心原理是通过脚本模拟人工操作,实现测试用例的自动执行与结果验证。在汽车电子领域,诊断服务测试是确保车辆ECU(电子控制单元)功能正常的重要环节,传统手动测试在面对海量用例和频繁回归时效率低下。本文聚焦于如何利用Python的pytest测试框架、Allure报告工具以及Excel数据驱动,构建一个与Vector CANoe仿真测试环境深度集成的自动化测试解决方案。该方案通过Python调用CANoe的COM接口,实现了诊断报文的自动发送与响应验证,并结合Al

weixin_30384217的博客 678

jvm学习笔记--基本结构

主要来学习jvm的基本结构 知识点1:什么是java虚拟机(你以为你知道,如果你看我下面的例子,你会发现你其实不知道) 第一步:先来写一个类: [code="java"] package test; public class JVMTestForJava { public static void main(String[] args) thro...

yangdingcai的专栏 655

OpenEuler22.04 快速部署Docker:华为云镜像源配置指南

本文详细介绍了在OpenEuler 22.04系统上快速部署Docker的完整流程。针对系统默认源版本老旧的问题,重点讲解了如何配置华为云镜像源以加速安装,并涵盖Docker引擎、Docker Compose的安装、服务启动验证、权限配置、镜像加速等核心步骤与常见问题排查,帮助用户高效搭建稳定的容器化开发环境。

http9protocoller的博客 174

Java中的JVM虚拟机的内存与直接内存

直接内存不属于java虚拟机内存,而属于操作系统内存当我调用直接内存(Direct Memory)常见于 NIO 操作时,用于数据缓冲区分配回收成本较高,但读写性能高不受 JVM 内存回收管理。

o676448的博客 573

银河麒麟v10-arm SEALOS离线部署k8s集群(v1.22.8)

示例 如果你想保存一个名为 "my_snapshot" 的 etcd 快照到指定的对象路径你可以使用以下命令: sealos etcd save --backupPath /root --name my_snapshot 如果文件名带时间戳:my_snapshot$(date +"%Y%m%d_%H%M%S") 会生成一个形如 20230913_143045 的时间戳。--restorePath string:指定快照恢复目录(默认为 "/opt/sealos/etcd-restore")。

xjudt的博客 3288

2021哈工大网安837考研初试经验贴

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

weixin_41797880的博客 6523

JVM专题之JVM内存和操作系统的进程的内存模型之间的关系

我们在谈及JVM内存的堆、虚拟机栈和本地方法栈、程序计数器和方法区等名词的时候,有没有想过一个问题。JVM是一个进程,那么天真的以为就该和操作系统进程内存模型结构保持一致,比如C/C++程序就是和操作系统的进程的内存模型保持一致。但是JVM内存管理中内存的划分明显和操作系统的进程内存模型有很大出入,那么他们之间的关系究竟是怎样的呢? 这一篇专题来解读这个问题。 一 操作系统进程的内存模型 1.1 进程的地址空间 进程的地址空间,也叫作虚拟地址空间或者逻辑地址空间,指的是这个进程中所有虚拟地址的集合,此时还没

happy19870612's blog 3466

国产麒麟系统中的PaddleOCR离线绿色部署:高效安全的文字识别新纪元

摘要:本文详细介绍了PaddleOCR在银河麒麟V10SP1系统上的离线部署方案。通过Conda虚拟环境隔离依赖,采用离线包安装方式实现无网络部署,支持80+语言识别。重点讲解了模型量化剪枝优化、多线程处理等性能调优技巧,并提供了完整的OCR识别代码示例。该方案具有数据本地化处理的安全优势,适用于医疗票据数字化等对隐私要求严格的场景,同时解决了模型加载失败、内存不足等常见问题。

墨夶的博客 1228

JVM及其内存模型

在我们垃圾回收的时候,我们往往将堆内存分成新生代和老生代(大小比例1:2),新生代中由Eden和Survivor0,Survivor1组成,三者的比例是8:1:1,新生代的回收机制采用复制算法,在Minor GC的时候,我们都留一个存活区用来存放存活的对象,真正进行的区域是Eden+其中一个存活区,当我们的对象时长超过一定年龄时(默认15,可以通过参数设置),将会把对象放入老生代,当然大的对象会直接进入老生代,老生代采用的回收算法是标记整理算法。每一个方法从调用到方法返回都对应着一个栈帧入栈出栈的过程。

qq_31856061的博客 541

【ROS】usb_cam相机标定

1. 唠叨两句 当我们要用相机做测量用途时,就需要做相机标定了,不然得到的计算结果会有很大误差,标定的内容包括三部分:内参,外参还有畸变参数。所以标定的过程就是要求得上面这些参数。 以前弄这个事估计挺麻烦,需要做实验和计算才能得到,现在通过ros的开源包几分钟就能完成相机标定,感激! 具体的内外参和畸变系数的说明,可以看看Reference里面的第一个链接,写得很详细。 2. 准备工作 要准备三样东西: usb_cam的ROS启动包 相机标定的ROS包 还有一个用于标定的棋盘格 1)usb_cam启动包

Will_Ye的博客 8202

【2026年华为暑期实习(非AI方向(通软&嵌软&测试&算法&数据科学))-4月8日-第一题- 包裹的编码】(题目+思路+Java&C++&Python解析+在线测试)

摘要:该问题要求将给定的十进制整数N转换为混合进制编码字符串,并处理回文检测。首先根据N的符号位确定编码首位(0或1),然后按输入的进制序列依次对N的绝对值进行取余和整除操作,得到编码数组。将数组元素转换为字母后生成字符串,若字符串为回文则添加"(palindrome)"后缀;否则输出最长回文子串(字典序最小)。算法采用中心扩展法检测回文,时间复杂度为O(L²),空间复杂度为O(L),其中L为字符串长度。

m0_73659489的博客 130

【JVM】JVM内存模型与操作系统内存模型(一)

可以这样理解:JVM内存模型其实就是JVM在启动的时候从操作系统内存中要了一块大内存,然后将这个大内存分成五个区域:方法区、堆区、虚拟机栈、本地方法栈、本地方法栈、程序计数器.其实叫JVM运行时区域更合适。但是要区分JVM内存模型与JMM(Java Memory Model)InstanceKlass:类的元信息(方法区)InstanceMirrorKlass:镜像类Class对象(堆区)四个名词:class文件:即硬盘上的.class文件。

Cover_sky的博客 1962

PyTorch实战(25)——使用PyTorch构建DQN模型

深度Q网络 (Deep Q-learning Network, DQN) 在强化学习领域取得了巨大的成功和广泛的应用,PyTorch 结合 gymnasium 库为我们提供了强大的工具,支持在各种强化学习环境中测试不同类型的深度强化学习模型。在本节中,我们使用 PyTorch 框架构建使用卷积神经网络架构的 DQN 模型,模型通过自主学习掌握 Atari 经典游戏《Pong》的操作策略,最终实现击败电脑对手的竞技目标。

盼小辉丶的博客 3469

一图解千愁,jvm内存从来没有这么简单过!

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。看到这张图的同学,千万不要到处分享。我们仅限于小范围讨论,因为这张图威力很大,是我花了10年时间才画出来的!了...

小姐姐味道 1247

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

一图解千愁,jvm内存从来没有这么简单过

看到这张图的同学,千万不要到处分享。我们仅限于小范围讨论,因为这张图威力很大,是我花了10年时间才画出来的! 了解了这张图,会让你对JVM内存的划分有更深入的理解,而不仅限于什么虚拟机栈、程序计数器等比较浅显的认知。 那么这张图有什么用呢?在进行内存排查的时候,我们需要了解到底是哪一个部分除了问题。如果你找不对地方,肯定切入就比较困难,这会耗费你大量的精力。 一台4GB的机器,一般使用Xmx分配给JVM的,肯定不能太多。比如3.5GB之类的。这就太贪婪了,很容易造成JVM异常死亡。这是为什么呢? 这

august5291的博客 280

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

一图解千愁,jvm内存从来没有这么简单过!(转载)

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。 看到这张图的同学,千万不要到处分享。我们仅限于小范围讨论,因为这张图威力很大,是我花了10年时间才画出来的! 了解了这张图,会让你对JVM内存的划分有更深入的理解,而不仅限于什么虚拟机栈、程序计数器等比较浅显的认知。 那么这张图有什么用呢?在进行内存排查的时候,我们需要了解到底是哪一个部分除了问题。如果你找不对地方,肯定切入就比较困难,这会耗费你大量的精力。 一台4GB的机器,一般使用Xmx分配给JVM的,肯定不能太多。比如3.5

Treasure003的博客 238

jvm 堆外内存_一图解千愁,JVM内存从来没有这么简单过

作者:小姐姐味道 看到这张图的同学,千万不要到处分享。我们仅限于小范围讨论,因为这张图威力很大,是我花了10年时间才画出来的!了解了这张图,会让你对JVM内存的划分有更深入的理解,而不仅限于什么虚拟机栈、程序计数器等比较浅显的认知。那么这张图有什么用呢?在进行内存排查的时候,我们需要了解到底是哪一个部分出了问题。如果你找不对地方,肯定切入就比较困难,这会耗费你大量的精力。一台4GB的机器,一般使用...

weixin_39944233的博客 153

jvm 堆外内存_一图解千愁,jvm内存从来没有这么简单过!

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。看到这张图的同学,千万不要到处分享。我们仅限于小范围讨论,因为这张图威力很大,是我花了10年时间才画出来的!了解了这张图,会让你对JVM内存的划分有更深入的理解,而不仅限于什么虚拟机栈、程序计数器等比较浅显的认知。那么这张图有什么用呢?在进行内存排查的时候,我们需要了解到底是哪一个部分除了问题。如果你找不对地方,肯定切入就...

weixin_39555715的博客 131

因为我从小就对Java感兴趣,所以我研究了JVM

从小我就对Java有着深厚的感情,算下来有几十年的Java经验了。当年的Java还是Sun公司的,我有着多年的Servlet经验,CURD经验,在现在已经被自我革新,转而研究人生的哲学。罢了,不吹了 为了保证文章的流畅性,我决定一口气把它写完。因为相关方面的培训做的多了,就不需要在写的时候参考资料、翻源代码。掐指一算,本文一个小时没花掉,但篇幅已经较长了。 长了,那就割断。本篇就定为内存排查的上篇,主要讲一些原理。为什么要讲原理?开车还需要了解汽车结构么? 这还真不能相比。 汽车很少坏,出了问题你会花钱给拖

m0_57227221的博客 144

Java内存故障?只是因为你不够帅!

不羡鸳鸯不羡仙,一行代码调半天。原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。从小我就对Java有着深厚的感情,算下来有几十年的Java经验了。当年的Jav...

小姐姐味道 477
上一篇: MySQL 可重复读,差点就让我背上了一个 P0 事故
下一篇: 必知必会——G1收集器详解及调优
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值