首页 > 系统相关 >JVM内存用量的再学习

JVM内存用量的再学习

时间:2023-12-05 09:33:30浏览次数:40  
标签:JVM 堆区 XX 内存 监控 用量

JVM内存用量的再学习


背景

最近解决一个SQLServer的问题耗时很久. 
最终找到了一个看似合理的问题解释. 
但是感觉不能只是总结于数据库方面 
因为为了解决这个问题增加了很多监控措施. 
所以想就这这个问题, 总结一下这次问题诊断过程中学习到的JVM相关知识. 

一个JVM的监控图表

堆区信息

image

类加载

image

栈信息

image


内存学习

启动脚本为:

-javaagent:./jmx_prometheus_javaagent-0.17.2.jar=8080:simple-config.yml -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 -XX:+SafepointTimeout   -XX:SafepointTimeoutDelay=2000  -XX:+UseCountedLoopSafepoints  -XX:-UseBiasedLocking -XX:+UnlockDiagnosticVMOptions -XX:GuaranteedSafepointInterval=0 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDetails -XX:-DisableExplicitGC -XX:+PrintGC -XX:+PrintGCDateStamps  -XX:-UseGCOverheadLimit -XX:+PrintGCTimeStamps -Xloggc:./dump/gclog -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dump -XX:NativeMemoryTracking=detail  -XX:+UnlockDiagnosticVMOptions  -Xmx24g -Xms24g 

关于监控的学习和了解

第一部分: 关于堆区
堆区设置的是24G内存

可以看到因为没有设置 老年代和青年带的比率, 就是按照默认的 2:1 进行分配
老年代 16G内存 青年代8G内存. 
幸存者区域 也是按照青年代的 8:1:1 进行默认分配,也就是只有青年代的 10%的代傲, 最大值是 805MB. 

内存的使用之, 基本上也达到了 16+8 =24G的堆区最大值. 

第二部分: 关于非堆区
1. 元数据区占用了 1.87GB, 接近 2GB的内存用量. 
2. 压缩元类区域: 200MB左右. 
3. Code cache 占用了 基本上默认的最大 240MB

监控到的费堆区合计使用了 2.5GB左右. 

通过acuator 或者是 jvm exporter 监控信息获得: 
两者合计为: 26.5GB

另外线程数数量较多, 最大值有 800个线程数 理论上Linux下面每一个线程至少要1MB的内存
所以这一块栈区的内存用量也不小, 也有接近1GB的区域. 

第三部分: 
同时进入系统查看 top 或者是 ps命令查看内存信息
1. top 后输入 大写的M 查看内存使用量较高的进程. 
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
32087 root      20   0   34.1g  29.6g 146164 S  27.6  62.7   1507:15 java

RES的内存足有  29.6G 比刚才计算的 26.5G  要多3GB的空间. 

2. 使用 ps -aux |grep java 进行查看
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     32087  243 62.7 35740952 31017360 ?   Sl   12月04 1507:17 

内存用量其实也是  30G左右. 

简单总结

设置堆区为 24G, 实际上堆区占整个进程的内存用量为:
24/30 = 80%

换句话说, 如果是容器内. 我们这样一个重型应用. 设置内存到32G的pod 的limit值
不建议 堆区的占用量超过80%  设置不建议超过 75% 

因为我ps 和 top 查看时堆区的内存应该已经下降了, 其他区域内存的占比要比
(30-24) 的6GB的使用量还要搞. 
这6GB 不仅仅包含监控中看到的 非堆区还有栈区 以及 GC使用的内存还有一部分直接内存
但是这一块应该是不包含加载到系统里面的缓存数据. 

另外监控中还可以看到. 类的数量其实非常多. 
程序启动完时就已经有了  16万个类, 运行完所有的功能后 类已经有 27.5万个类

计划下次有时间总结一一下 类和对象的关系. 

标签:JVM,堆区,XX,内存,监控,用量
From: https://www.cnblogs.com/jinanxiaolaohu/p/17876507.html

相关文章

  • Java 内存分析工具 Arthas 介绍与示例讲解
    目录一、概述二、Arthas安装三、Arthas主要组成结构四、Arthas通信主要流程五、Arthas快速入门讲解1)启动Arthas2)基础命令介绍3)jvm相关1、dashboard(实时数据面板)2、Thread(线程相关堆栈信息)3、jvm(查看当前JVM的信息)4、memory(查看JVM的内存信息)5、sysprop(查看/修改属性)6、s......
  • 内存管理相关概念 (翻译 by chatgpt)
    原文:https://www.kernel.org/doc/html/latest/admin-guide/mm/concepts.htmlThememorymanagementinLinuxisacomplexsystemthatevolvedovertheyearsandincludedmoreandmorefunctionalitytosupportavarietyofsystemsfromMMU-lessmicrocontrollerst......
  • C语言-动态内存管理(三)
    动态内存管理第一部分解释了什么是动态内存管理,有什么用,以及一些函数,第二部分主要讨论了动态内存在使用的时候会出现一些经典的错误,需要注意。那么这个第三部分主要讨论一些有关动态内存管理有关的比较经典的笔试题。题目1请问运行Test函数会有什么样的结果?voidGetMemory(char*p)......
  • Java获取CPU占用率、内存占用率
    packagetest.lyh.test;importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.JSONObject;importjava.lang.management.ManagementFactory;importjava.lang.management.OperatingSystemMXBean;importjava.math.BigDecimal;importjava.math.RoundingMode......
  • Day12 jvm 内存模型JMM
    1.jvm内存模型JMM原帖链接JMM控制Java线程之间的通信,决定一个线程对共享变量的写入何时对另一个线程可见。每条线程在自己的工作内存中对共享变量(副本)进行操作,JMM再负责把这些操作同步到主内存中JVM1.8用Metaspace(元空间)(在JVM外的本地内存中)取代了方法区(MethodArea)(在......
  • 软件测试/人工智能|Python 变量解析:从基础概念到内存地址探究
    变量什么是变量?变量是在程序中用于存储数据的名称。它们可以存储各种类型的数据,比如数字、文本、列表、字典等等。变量类型在介绍变量时,可以提及Python中常见的变量类型,例如整数、浮点数、字符串、布尔值、列表、元组、字典等。如下所示:a=1b='muller'c='123'd=......
  • 聊一聊 .NET高级调试 中的一些内存术语
    一:背景1.讲故事在高级调试的旅程中,经常会有一些朋友问我什么是工作集(内存),什么是提交大小,什么是VirtualSize,什么是WorkingSet。。。截图如下:既然有很多朋友问,这些用口头也不怎么好描述,刚好上午有时间就系统的聊一下吧。二:内存术语解读1.VirtualSize是什么可......
  • JVM-垃圾回收器
    G1收集器G1收集器的内存结构完全区别去CMS,弱化了CMS原有的分代模型(分代可以是不连续的空间),将堆内存划分成一个个Region(1MB~32MB,默认2048个分区),这么做的目的是在进行收集时不必在全堆范围内进行。它主要特点在于达到可控的停顿时间,用户可以指定收集操作在多长时间内完成,即G1提......
  • go 内存管理
    协程栈go栈的位置1.Go协程栈位于Go-堆内存上2.Go堆内存位于操作系统虚拟内存上go栈的工作流程以main.main为出发点要记录runtime.main的栈基地址记录a和b的局部变量值开辟一个空间记录sum函数的返回值记录b和a的值,这里是为了方便sum在执行时候,......
  • C语言-动态内存管理(二)
    第二部分主要是常见的动态内存错误动态内存错误1.对NULL指针的解引用操作对NULL指针的解引用操作,什么意思呢?有些同学写代码的时候比较冲动,如下:intmain(){int*p=(int*)malloc(40);for(inti=0;i<10;++i){*(p+1)=i;}free(p);p=NULL;......