前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2024-4-19 群讨论:JVM 堆外内存如何查看?

2024-4-19 群讨论:JVM 堆外内存如何查看?

作者头像
干货满满张哈希
发布2024-05-25 09:00:14
1320
发布2024-05-25 09:00:14
举报
文章被收录于专栏:干货满满张哈希

JVM 堆外内存如何查看?

参考:https://juejin.cn/post/7225871227743043644

分为:

  1. 通过 Native Memory Tracking 能看到的:
    1. Java堆内存,所有 Java 对象分配占用内存的来源
    2. 2.元空间,JVM 将类文件加载到内存中用于后续使用占用的空间,注意是 JVM C++ 层面的内存占用,主要包括类文件中在 JVM 解析为 C++ 的 Klass 类以及相关元素。
    3. C++ 字符串即符号(Symbol)占用空间,前面加载类的时候,其实里面有很多字符串信息(注意不是 Java 字符串,是 JVM 层面 C++ 字符串),不同类的字符串信息可能会重复(
    4. 线程占用内存,主要是每个线程的线程栈,我们也只会主要分析线程栈占用空间(在第五章),其他的管理线程占用的空间很小,可以忽略不计。
    5. JIT编译器本身占用的空间以及JIT编译器编译后的代码占用空间
    6. Arena 数据结构占用空间,我们看到 Native Memory Tracking 中有很多通过 arena 分配的内存,这个就是管理 Arena 数据结构占用空间。
    7. JVM Tracing 占用内存,包括 JVM perf 以及 JFR 占用的空间。
    8. 写 JVM 日志占用的内存(-Xlog 参数指定的日志输出,并且 Java 17 之后引入了异步 JVM 日志-Xlog:async,异步日志所需的 buffer 也在这里)
    9. JVM 参数占用内存,我们需要保存并处理当前的 JVM 参数以及用户启动 JVM 的是传入的各种参数(有时候称为 flag)
    10. JVM 安全点占用内存,是固定的两页内存(我这里是一页是 4KB,后面第二章会分析这个页大小与操作系统相关),用于 JVM 安全点的实现,不会随着 JVM 运行时的内存占用而变化。
    11. Java 同步机制(例如 synchronized,还有 AQS 的基础 LockSupport)底层依赖的 C++ 的数据结构,系统内部的 mutex 等占用的内存。
    12. JVM TI 相关内存,JVMTI 是 Java 虚拟机工具接口(Java Virtual Machine Tool Interface)的缩写。它是 Java 虚拟机(JVM)的一部分,提供了一组 API,使开发人员可以开发自己的 Java 工具和代理程序,以监视、分析和调试 Java 应用程序。JVMTI API 是一组 C/C++ 函数,可以通过 JVM TI Agent Library 和 JVM 进行交互。开发人员可以使用 JVMTI API 开发自己的 JVM 代理程序或工具,以监视和操作 Java 应用程序。
    13. Java 字符串去重占用内存:Java 字符串去重机制可以减少应用程序中字符串对象的内存占用。 在 Java 应用程序中,字符串常量是不可变的,并且通常被使用多次。这意味着在应用程序中可能存在大量相同的字符串对象,这些对象占用了大量的内存。Java 字符串去重机制通过在堆中共享相同的字符串对象来解决这个问题。当一个字符串对象被创建时,JVM 会检查堆中是否已经存在相同的字符串对象。如果存在,那么新的字符串对象将被舍弃,而引用被返回给现有的对象。这样就可以减少应用程序中字符串对象的数量,从而减少内存占用。 但是这个机制一直在某些 GC 下表现不佳,尤其是 G1GC 以及 ZGC 中,所以默认是关闭的,可以通过 -XX:+UseStringDeduplication 来启用。
    14. JVM GC需要的数据结构与记录信息占用的空间,这块内存可能会比较大,尤其是对于那种专注于低延迟的 GC,例如 ZGC。其实 ZGC 是一种以空间换时间的思路,提高 CPU 消耗与内存占用,但是消灭全局暂停。之后的 ZGC 优化方向就是尽量降低 CPU 消耗与内存占用,相当于提高了性价比。
    15. JVM内部(不属于其他类的占用就会归到这一类)与其他占用(不是 JVM 本身而是操作系统的某些系统调用导致额外占的空间),不会很大。但是这里会因为某些 bug 导致很大,例如:
      1. https://bugs.openjdk.org/browse/JDK-8305994 。 Java 15,16 引入的 bug,17 低版本存在这个问题,21 修复的,在 17.0.8 port 回 17 的。
  2. 开启 Native Memory Tracking 本身消耗的内存
  3. 通过 Native Memory Tracking 看不到的:
    1. DirectBuffer:通过 ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 分配的,底层基于 JNI + 系统调用,不会被 Native Memory Tracking 采集
    2. MMAP Buufer:通过 MappedByteBuffer mmap = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileChannel.size()); 分配的,底层基于 JNI + 系统调用,不会被 Native Memory Tracking 采集

目前,Native Memory Tracking 已经可以通过 JFR 查看(Java 22):

b06c75895b14c29496503fc30224769f.jpeg
b06c75895b14c29496503fc30224769f.jpeg
855e42fead12291216c94184625a7f3c.jpeg
855e42fead12291216c94184625a7f3c.jpeg

查看 Native Memory Tracking 看不到的 Direct Buffer 以及 MMAP Buffer 的方式,可以通过 JMX 查看,这里给一个 Jconsole 的截图,大家通过截图的这个路径写代码访问 MBean 就能看到:

e1e88b9114911695b66731fa7917e1c9.jpeg
e1e88b9114911695b66731fa7917e1c9.jpeg

个人简介:个人业余研究了 AI LLM 微调与 RAG,目前成果是微调了三个模型:

  1. 一个模型是基于 whisper 模型的微调,使用我原来做的精翻的视频按照语句段落切分的片段,并尝试按照方言类别,以及技术类别分别尝试微调的成果。用于视频字幕识别。
  2. 一个模型是基于 Mistral Large 的模型的微调,识别提取视频课件的片段,辅以实际的课件文字进行识别微调。用于识别课件的片段。
  3. 最后一个模型是基于 Claude 3 的模型微调,使用我之前制作的翻译字幕,与 AWS、Go 社区、CNCF 生态里面的官方英文文档以及中文文档作为语料,按照内容段交叉拆分,进行微调,用于字幕翻译
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JVM 堆外内存如何查看?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档