简单的springboot应用部署后内存占用量过大问题排查

news2024/11/26 3:41:40

1.问题背景

需要部署一个演示环境。所有组件都要部署到一台服务器,采用Docker容器部署,发现多个简单的springboot应用占用内存高达2G,后续的应用因为内存不足就部署不了了。排查下内存占用大的原因:
docker stats命令:
在这里插入图片描述

2.排查步骤:

不想看过程的可以直接查看文末总结

jstats查下应用堆内存情况:

[root@968204e40b opt]# jstat -gc 1 1000 10
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
27136.0 26624.0  0.0    0.0   2508800.0 1676722.1  320512.0   23699.8   59160.0 56533.7 8320.0 7819.9     13    0.414   3      0.280
27136.0 26624.0  0.0    0.0   2508800.0 1676722.1  320512.0   23699.8   59160.0 56533.7 8320.0 7819.9     13    0.414   3      0.280
27136.0 26624.0  0.0    0.0   2508800.0 1676722.1  320512.0   23699.8   59160.0 56533.7 8320.0 7819.9     13    0.414   3      0.280

EC EU区居然比OC OU区还大,青年代大于老年代 也就是说青年代没有设置或者设置的过大了。青年代过大触发GC频率过低。造成大量垃圾对象堆积在青年代不回收。而Eden区多次扩容导致。

NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数

jmap查看应用内存详情:

-- 问题发现 eden区内存大
[root@576aea1126d9 opt]# jmap -heap 1
Attaching to process ID 1, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.191-b12

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 8317304832 (7932.0MB)
   NewSize                  = 173015040 (165.0MB)
   MaxNewSize               = 2772434944 (2644.0MB)
   OldSize                  = 347078656 (331.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 2402811904 (2291.5MB)
   used     = 1686518448 (1608.3893280029297MB) #应用刚启动 eden区就使用了1.6G内存  
   free     = 716293456 (683.1106719970703MB)
   70.18936626676542% used
From Space:
   capacity = 27262976 (26.0MB)
   used     = 0 (0.0MB)
   free     = 27262976 (26.0MB)
   0.0% used
To Space:
   capacity = 27787264 (26.5MB)
   used     = 0 (0.0MB)
   free     = 27787264 (26.5MB)
   0.0% used
PS Old Generation
   capacity = 350224384 (334.0MB)
   used     = 25793584 (24.598678588867188MB)
   free     = 324430800 (309.4013214111328MB)
   7.364873829002152% used

27924 interned Strings occupying 2735400 bytes.

查看启动命令:

docker run -d --cap-add=SYS_PTRACE -e JAVA_OPTS=’ -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Xms128m -Xmx128m -Xmn32m -Xss256k -XX:SurvivorRatio=6 -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom -Dlog4j2.formatMsgNoLookups=true’ 【镜像:版本】

–cap-add=SYS_PTRACE 用来解决docker容器内不能运行 jmap命令

说明启动参数:JAVA_OPTS 并没有生效。
一顿百度加实验后只有:将JVM参数加入Dockerfile中才生效

FROM med/oraclejdk:8u191
ADD hcp-terminal-app-1.0.0.jar /opt/app.jar
WORKDIR /opt
EXPOSE 8080
ENTRYPOINT ["java", "-jar","-XX:MaxMetaspaceSize=256m","-Xms128m","-Xmx128m","-Xmn32m","-XX:SurvivorRatio=6","-Dlog4j2.configuration=/opt/log4j2.properties","app.jar","--spring.config.location=/opt/application.yaml"]

重新构建镜像后启动
修改参数后内存使用量情况:

[root@15972b64bff3 opt]# jps
1 jar
205 Jps
[root@15972b64bff3 opt]# jstat -gc 1 1000 2
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
1536.0 1536.0 256.0   0.0   29696.0   5130.0   98304.0    76430.8   83712.0 79187.7 11520.0 10663.5    406    1.784   3      0.329    2.113
1536.0 1536.0 256.0   0.0   29696.0   5130.0   98304.0    76430.8   83712.0 79187.7 11520.0 10663.5    406    1.784   3      0.329    2.113

#eden区使用量[EU]下去了,OU使用量也是合理的

[root@15972b64bff3 opt]# jmap -heap 1
Attaching to process ID 1, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.191-b12

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 134217728 (128.0MB)
   NewSize                  = 33554432 (32.0MB)
   MaxNewSize               = 33554432 (32.0MB)
   OldSize                  = 100663296 (96.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 6
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 260046848 (248.0MB)
   MaxMetaspaceSize         = 268435456 (256.0MB)
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 30408704 (29.0MB)
   used     = 7501416 (7.153907775878906MB)
   free     = 22907288 (21.846092224121094MB)
   24.668647503030712% used
From Space:
   capacity = 1572864 (1.5MB)
   used     = 753664 (0.71875MB)
   free     = 819200 (0.78125MB)
   47.916666666666664% used
To Space:
   capacity = 1572864 (1.5MB)
   used     = 0 (0.0MB)
   free     = 1572864 (1.5MB)
   0.0% used
PS Old Generation
   capacity = 100663296 (96.0MB)
   used     = 71246592 (67.946044921875MB)
   free     = 29416704 (28.053955078125MB)
   70.77713012695312% used

27238 interned Strings occupying 2666864 bytes.

至此:问题解决

3.总结:

问题排查步骤:

  1. docker stats 命令查看docker容器内存和CPU使用情况
  2. 高内存使用量应用,进入容器 jps查询java 进程id
  3. jstat 命令查看年轻代和老年代内存使用量和分布。
  4. jmap查看内存详情,分析问题原因为:青年代没有设置或者设置的过大了。青年代过大触发GC频率过低。造成大量垃圾对象堆积在青年代不回收。而Eden区多次扩容导致。
  5. 设置JVM参数限制内存大小:-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Xms128m -Xmx128m -Xmn32m -Xss256k -XX:SurvivorRatio=6 -XX:+UseConcMarkSweepGC【数值可以自己设置不必照抄】
  6. docker容器运行时设置参数-e JAVA_OPTS 没有生效。
  7. 为设置JVM参数多次实验 Dockerfile中设置的参数可以生效:ENTRYPOINT [“java”, “-jar”,“-XX:MaxMetaspaceSize=256m”,“-Xms128m”,“-Xmx128m”,“-Xmn32m”,“-XX:SurvivorRatio=6”,“app.jar”,“–spring.config.location=/opt/application.yaml”]
  8. 重新构建应用镜像后部署问题解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/941120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ucharts修改ToolTip边框阴影文字居中

ucharts修改ToolTip边框阴影文字居中 效果 Demo 链接: https://pan.baidu.com/s/1k0FxmBPKAHlHksFR3YQSlQ 提取码:ytv7

在vue.config.js中配置文件路径代理名

今天在公司项目中看到一个非常有趣的导入路径 crud 先是一蒙 这是个啥 突然想起一个被自己遗漏的知识点 在vue.config.js中配置路径指向 这里 我们随便找一个vue项目 在src下找到 components 目录 如果没有就创建一个 下面找到HelloWorld.vue 如果没有也是自己创建一个就好 然…

LabVIEW开发异步电动机定子故障在线诊断系统

LabVIEW开发异步电动机定子故障在线诊断系统 三相感应电机(IM)因其简单性、坚固性和可靠性而广泛用于许多工业应用。然而,对于需要高可靠性的特定领域,如汽车、航空航天、军事和核能,使用经典的三相IM似乎不再适用&am…

JavaScript函数复习

这节课我们来通过我们之前学过的函数来逐渐完善! const yearsUntilRetiremen (birthyear, firstName) > {const age 2037 - birthyear;const retirement 65 - age;return ${firstName}还有${retirement}年就退休了!;}这个是我们之前写的代码&…

循环结构(个人学习笔记黑马学习)

while循环语句 在屏幕中打印0~9这十个数字 #include <iostream> using namespace std;int main() {int i 0;while (i < 10) {cout << i << endl;i;}system("pause");return 0; } 练习案例: 猜数字 案例描述:系统随机生成一个1到100之间的数字&…

数字电路-二进制学习

什么是二进制&#xff1f; 数字电路 中 只有 高电平 和低电平 就是 1 和0 进位规则是“逢二进一”&#xff0c;借位规则是“借一当二”。 二进制、八进制 、十进制、十六进制 二进制 有两个数来表示 &#xff1a; 0、1 八进制 有8个数来表示 &#xff1a; 0、1、2、3、4、…

ASEMI肖特基模块MBR400100CT功能应用介绍

编辑-Z 肖特基模块MBR400100CT是一款高性能半导体器件&#xff0c;常用于电源和开关电路中。该模块采用肖特基二极管技术&#xff0c;具有低导通压降和高速开关特性&#xff0c;适合在高频率和高温环境下使用。 肖特基二极管是基于金属-半导体接触的特殊结构的二极管。与传统P…

Go几种读取配置文件的方式

比较有名的方案有 使用viper管理配置[1] 支持多种配置文件格式&#xff0c;包括 JSON,TOML,YAML,HECL,envfile&#xff0c;甚至还包括Java properties 支持为配置项设置默认值 可以通过命令行参数覆盖指定的配置项 支持参数别名 viper[2]按照这个优先级&#xff08;从高到低&am…

博客系统后台前端UI设计

效果展示 API编写 index.js import axios from "./request"const fastdfs {delete: file/fastdfs/delete } const permission {search: "/sys/permission/search",add: "/sys/permission/add",update: "/sys/permission/update",d…

适合新手程序员的体质,一键代码审查轻松搞定

很多刚入行的程序员会面临一个问题&#xff0c;写完代码进行运行会出现很多bug但是不能准确的定位问题的所在&#xff0c;很多人对于自己的代码结构和层次也摸不着头脑&#xff0c;为了提高代码的质量经常会消耗大量的人力物力来做这件事情。 在&#xff08;软件工程的事实与谬…

阻塞io读取内核驱动变量值

应用程序&#xff1a; #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <sys/ioctl.h> #include "head.…

Spring MVC 四:Context层级

这一节我们来回答上篇文章中避而不谈的有关什么是RootApplicationContext的问题。 这就需要引入Spring MVC的有关Context Hierarchy的问题。Context Hierarchy意思就是Context层级&#xff0c;既然说到Context层级&#xff0c;说明在Spring MVC项目中&#xff0c;可能存在不止…

Linux学习之DNS服务的原理

DNS服务一些理论 域名系统&#xff08;Domain Name System&#xff0c;DNS&#xff09;是互联网的核心应用服务&#xff0c;可以通过IP地址查询到域名&#xff0c;也可以通过域名查询到IP地址。 FQDN&#xff08;Full Qualified Domain Name&#xff09;是完全限定域名&#xf…

解决FreeRTOS程序跑不起来,打印调试却提示“Error:..\FreeRTOS\port\RVDS\ARM_CM3\port.c,244“的方法

前言 今天来分享一个不会造成程序编译报错&#xff0c;但会使程序一直跑不起来&#xff0c;并且通过调试会发现有输出错误提示的错误例子分析&#xff0c;话不多说&#xff0c;我们就直接开始分析~ 首先&#xff0c;我们说过这个例子在编译时候没有明示的错误提示&#xff0c…

Excel·VBA二维数组组合函数、组合求和

目录 1&#xff0c;二维数组组合函数举例 2&#xff0c;组合求和 之前的文章《ExcelVBA数组组合函数、组合求和》和《ExcelVBA数组排列函数》&#xff0c;都是针对一维数组的组合和排列 二维数组组合&#xff1a;对一个m行*n列的二维数组&#xff0c;每行抽取1个元素进行组合&a…

[管理与领导-56]:IT基层管理者 - 扩展技能 - 1 - 时间管理 -3- 帮助下属提升效能(辅导与激励)

前言&#xff1a; 对下属的辅导是管理者一个重要的职责&#xff0c;帮助下属者提升时间效能也辅导下属的一个职责。 管理者与下属&#xff0c;管理者与团队是“共生”的关系&#xff0c;管理者提升下属的时间效能&#xff0c;就是提升团队的效能&#xff0c;也就是提升了自己…

计算机视觉-LeNet

目录 LeNet LeNet在手写数字识别上的应用 LeNet在眼疾识别数据集iChallenge-PM上的应用 LeNet LeNet是最早的卷积神经网络之一。1998年&#xff0c;Yann LeCun第一次将LeNet卷积神经网络应用到图像分类上&#xff0c;在手写数字识别任务中取得了巨大成功。LeNet通过连续使用…

Linux各类性能分析工具用法详解

文章目录 静态性能分析工具文件系统观测工具虚拟文件系统(VFS)分析工具磁盘管理工具进程资源占用监测系统库调用分析工具网络配置防火墙配置多路径配置进程调度系统命令操作查看硬件信息磁盘管理网络端口硬件信息 监测工具内核调用监测系统调用监测系统函数调用监测系统性能监测…

【VRTK4.0运动专题】轴移动AxisMove(真实身体的移动)

文章目录 1、概览2、释义3、属性设置 1、概览 2、释义 “竖直轴”控制的行为“水平轴”控制的行为1Vertical-Slide 滑动Horizontal-Slide 滑动2Vertical-Slide 滑动Horizontal-SmoothRotate 转动3Vertical-Slide 滑动Horizontal-SnapRotate 转动&#xff08;不连续&#xff09…

PDF制作成翻页电子书

在日常工作中&#xff0c;大部分人使用的都是PDF文档发送给客户&#xff0c;但是PDF文档通常是静态的&#xff0c;缺乏交互性和视觉吸引力。那你有没有想过把它转换成翻页的电子书呢&#xff1f; 小编将告诉你操作步骤&#xff0c;非常简单 1.搜索FLBOOK在线制作电子杂志平台 …