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

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. 重新构建应用镜像后部署问题解决。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件工程(十五) 行为型设计模式(一)

1、责任链模式 简要说明 通过多个对象处理的请求,减少请求的发送者与接收者之间的耦合。将接受对象链接起来,在链中传递请求,直到有一个对象处理这个请求。 速记关键字 传递职责 类图如下 由类图可以比较容易的看出来,其实就是自己关联自己,形成了一个链,并且自己有…

Failed to start bean ‘documentationPluginsBootstrapper‘

问题描述 在集成redisson-spring-boot-starter时,项目启动时报如下错误 之前在集成swagger3.0的时候,遇到过同样的问题,原因是Springfox使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.7.X使用的是PathPatternMat…

为什么JVM调优一般都是针对堆内存的,以及堆内存的设置对GC的影响

1、为什么JVM调优一般都是针对堆内存的? 首先JVM的四部分组成:ClassLoader(类装载器)、Runtime data area 运行数据区、Execution Engine 执行引擎、Native Interface 本地接口。 其中运行数据区(Runtime Data Area&am…

性能优化维度

CPU 首先检查 cpu,cpu 使用率要提升而不是降低。其次CPU 空闲并不一定是没事做,也有可能是锁或者外部资源瓶颈。常用top、vmstat命令查看信息。 vmstat 命令: top: 命令 IO iostat 命令: Memory free 命令: 温馨提示&#xff1a…

图解算法--查找算法

目录 查找算法 一、顺序查找 二、二分法查找 三、插值查找法 四、斐波那契查找法 查找算法 查找算法根据数据量的大小,可以将其分为以下两种 内部查找:内部查找是指在内存或内部存储器中进行查找操作的算法。内部查找适用于数据量较小、存储在内存…

Mysql的page,索引,Explain Type等基本常识

Mysql的基本问题 Mysql 为什么建议使用自增id? 因为id(主键)是自增的话,那么在有序的保存用户数据到页中的时候,可以天然的保存,并且是在聚集索引(id)中的叶子节点可以很好的减少插…

Java自定义捕获异常

需求分析 ElectricalCustomerVO electricalCustomerVO new ElectricalCustomerVO(); electricalCustomerVO.setElcNumber(chatRecordsLog.getDeviceNumber()); List<ElectricalCustomerVO> electricalCustomerlist electricalCustomerMapper.selectElectricalCustomer…

Git中smart Checkout与force checkout

Git中smart Checkout与force checkout 使用git进行代码版本管理,当我们切换分支有时会遇到这样的问题&#xff1a; 这是因为在当前分支修改了代码&#xff0c;但是没有commit,所以在切换到其他分支的时候会弹出这个窗口&#xff0c; 提示你选force checkout或者smart checko…

海外ios应用商店优化排名因素之视频预览与截图

当我们找到感兴趣的应用程序并转到该应用程序的页面时&#xff0c;首先引起注意的是预览视频。视频旨在以更具吸引力的方式展示应用程序的用户体验和UI。视频长度最多为30秒&#xff0c;其中前5秒最为重要&#xff0c;一定要让它尽可能引人注目。 1、关于优化预览视频的提示。…

改进YOLOv8系列:原创改进创新点 SIoU-NMS,EIoU-NMS,DIoU-NMS,CIoU-NMS,GIoU-NMS改进

💡该教程为属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 💡本篇文章为YOLOv8独家原创改进:原创改进创新点 DIoU-NMS,SIoU-NMS,EIoU-NMS,CIoU-NMS,GIoU-NMS改进。 💡对自己数据集改进有效的话,可以直接当做自己的原创改…

前端需要理解的设计模式知识

设计模式的原则&#xff1a;1. 单一职责原则&#xff08;一个对象或方法只做一件事&#xff09; 2. 最少知识原则&#xff08;尽可能少的实体或对象间互相作用&#xff09; 3. 开放封闭原则&#xff08;软件实体具有可扩展且不可修改&#xff09; 设计模式是通过代码设计经验总…

理论转换实践之keepalived+nginx实现HA

背景&#xff1a; keepalivednginx实现ha是网站和应用服务器常用的方法&#xff0c;之前项目中单独用nginx实现过负载均衡和服务转发&#xff0c;keepalived一直停留在理论节点&#xff0c;加之最近工作编写的一个技术文档用到keepalived&#xff0c;于是便有了下文。 服务组件…

学习笔记|认识数码管|控制原理|数码管实现0-9的显示|段码跟位码|STC32G单片机视频开发教程(冲哥)|第九集:数码管静态显示

文章目录 1.认识数码管2.控制原理十进制转换为任意进制其它进制转十进制 3.数码管实现0-9的显示1.用数组定义0-9的内码段码跟位码的区别2.尝试用延时实现0-9的循环显示3.用按键控制数字的加或者减。 总结课后练习&#xff1a; 1.认识数码管 数码管按段数可分为七段数码管和八段…

【触动精灵】IDE 连接设备

文章目录 1. 安装 TSStudio2. 下载 蒲公英VPN使用方法后台管理设备 3. 下载 雷电模拟器雷电设置安装蒲公英安装触动精灵 4. IDE 连入设备 1. 安装 TSStudio 登录触动官网&#xff0c;注册触动账号。 左下角开发工具&#xff0c;选择下载 IDE 触动脚本编辑器界面如下&#xff…

计算机毕设之Python的高校成绩分析(含文档+源码+部署)

本系统阐述的是一个高校成绩分析系统的设计与实现&#xff0c;对于Python、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计&#xff0c;描述&#xff0c;实现和分析与测试方面来表明开发的过程。开发中使用了 django框架和MySql数据库技术搭建系统的整体架构。…

[Android]JNI的基础知识

目录 1.什么是JNI 2.配置JNI开发环境NDK 3.创建Native C类型的项目 4. 了解CMakeLists.txt 文件 5.了解native-lib.cpp 文件 6.在 Android 的 MainActivity 中调用 native-lib.cpp 中实现的本地方法 1.什么是JNI JNI&#xff08;Java Native Interface&#xff09;是一…

Stable Diffusion 提示词入门指南

前言 本文主要讲解 Stable Diffusion &#xff08;下文简称 SD&#xff09;提示词的用法&#xff0c;帮助大家生成更高质量的图片 本章节主要讲解文生图&#xff0c;其他类型读者可以自行探索。同时本文主要是以 Stable Diffusion Discard 的形式生成图片 如果各位对于图片隐…

vulhub之MinIO信息泄露漏洞(CVE-2023-28432)

文章目录 0x01 前言0x02 漏洞描述0x03 影响范围0x04 漏洞复现1.启动环境2.查看端口3.构造POC 0x05 修复建议 0x01 前言 本次测试仅供学习使用&#xff0c;如若非法他用&#xff0c;与本文作者无关&#xff0c;需自行负责&#xff01;&#xff01;&#xff01; 0x02 漏洞描述 …

AR地图微信小程序:数字化时代下地图应用的新突破

随着数字化时代的到来&#xff0c;地图应用成为人们日常生活中不可或缺的工具。而随着增强现实&#xff08;AR&#xff09;技术的快速发展&#xff0c;AR地图微信小程序应运而生&#xff0c;为用户提供了一种全新的地图导航体验。本文将深入探讨AR地图微信小程序的专业性和思考…

茶凳浅谈-使用QCA7006AQ 让电动汽车成为智慧电网的一环

前言: 智慧电网一词相信大家都已经耳熟能详。智能电网是指采用先进的电力技术和设备、信息与通信技术&#xff0c;系统地实现电网的智能型监测、分析和决策控制&#xff0c;支持新型能源发电和灵活优质用电&#xff0c;具有高自动化水平&#xff0c;并有一定自愈、互动功能的安…