最近2天发现网关有个节点出现可用内存不足告警。由于运维的jvm内存分配策略导致我们操作系统可用内存离告警只有382M的可用空间。jdk1.8
一、节点内存使用监控
从监控上我们可以看出来应用使用jvm内存没有发现有问题。但是此节点cup使用率比较高。
1、物理内存、 Cached、Buffers、Free监控 | 2、old、eden代内存使用 | 3、Survivor、Metaspace区域 | 4、线程数、cup使用 |
![image.png]([object Object]&name=image.png&originHeight=558&originWidth=1446&originalType=binary&ratio=1&size=156615&status=done&style=none&taskId=uea20f3c7-3031-4f4a-97ac-4d89fff651a&width=723) | ![image.png]([object Object]&name=image.png&originHeight=914&originWidth=2754&originalType=binary&ratio=1&size=227854&status=done&style=none&taskId=u098c0e35-93e2-4bff-819d-200b17e85ec&width=1377) | ![image.png]([object Object]&name=image.png&originHeight=956&originWidth=2768&originalType=binary&ratio=1&size=546511&status=done&style=none&taskId=ud7228405-3f95-4d0d-8a7e-603785f5351&width=1384) | ![image.png]([object Object]&name=image.png&originHeight=1160&originWidth=2852&originalType=binary&ratio=1&size=309086&status=done&style=none&taskId=ua5758a56-2886-46b7-a366-703b5f7b1bb&width=1426) |
![image.png]([object Object]&name=image.png&originHeight=844&originWidth=2858&originalType=binary&ratio=1&size=125257&status=done&style=none&taskId=ud32ff5e6-d93b-4008-8118-0471e6920de&width=1429) | ![image.png]([object Object]&name=image.png&originHeight=992&originWidth=2838&originalType=binary&ratio=1&size=913576&status=done&style=none&taskId=uc0690218-07d5-401b-95eb-1140303e247&width=1419) | ![image.png]([object Object]&name=image.png&originHeight=908&originWidth=2798&originalType=binary&ratio=1&size=198141&status=done&style=none&taskId=uddb22cdb-252c-46bb-b44a-00aa541cf2a&width=1399) | ![image.png]([object Object]&name=image.png&originHeight=1364&originWidth=2798&originalType=binary&ratio=1&size=402651&status=done&style=none&taskId=u8b3bc64b-ea1b-4d9f-8fcf-41bb59c58cc&width=1399) |
二、应用使用内存明细
2.1、操作系统内存明细
//1、查看操作系统内存使用,不是问题出现时刻的
free -m
total used free shared buff/cache available
Mem: 3950 3102 146 202 701 404
Swap: 0 0 0
2.1.1、Mem
total:表示物理内存总量
used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用
free:未被分配的内存
shared:共享内存,一般系统不会用到,这里也不讨论
buff:系统分配但未被使用的buffer大小
cache:系统分配但未被使用的cache大小
available 是应用程序认为可用内存数量,available = free + buffer + cache这点没有证实。Linux解释
2.1.2、buffer 与 cache 区别
buffers 就是存放要输出到disk(块设备)的数据,缓冲满了一次写,提高io性能(内存 -> 磁盘)
cached 就是存放从disk上读出的数据,常用的缓存起来,减少io(磁盘 -> 内存)
buffer 和 cache,两者都是RAM中的数据。
简单来说,buffer是即将要被写入磁盘的,cache是被从磁盘中读出来的
2.1.2.1、 buffer缓冲
buffer是用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。
缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。
2.1.2.2、cache缓存
cache经常被用在磁盘的I/O请求上,如果有多个进程都要访问某个文件,于是该文件便被做成cache以方便下次被访问,这样可提供系统性能。缓存(cached)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。
2.2、java应用内存使用
- **应用使用内存计算 = **MaxHeapSize+CompressedClassSpaceSize+MetaspaceSize+应用的buffer、cache+ 栈使用内存【此处是我的理解】
- **应用使用内存 = **2048+1024+20+262+160*1 = 3514M
2.2.1、堆内存结构
查看应用各个部分使用的内存大小。详细参数看我以前的文章。
#jmap -heap PID 此非问题机器统计
jmap -heap 12009
Attaching to process ID 12009, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
#堆最大分配内存 我司策略Xms = Xmx
MaxHeapSize = 2147483648 (2048.0MB)
#新生代初始化分配内存
NewSize = 536870912 (512.0MB)
#新生代最大内存
MaxNewSize = 536870912 (512.0MB)
#最大堆分配内存
OldSize = 1610612736 (1536.0MB)
NewRatio = 2
SurvivorRatio = 8
#元空间使用内存
MetaspaceSize = 21807104 (20.796875MB)
#元空间分配内存
CompressedClassSpaceSize = 1073741824 (1024.0MB)
#最大元空间
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
# Young Space内存大小与使用率
PS Young Generation
Eden Space:
capacity = 488636416 (466.0MB)
used = 57412144 (54.75248718261719MB)
free = 431224272 (411.2475128173828MB)
11.749460768801972% used
From Space:
capacity = 21495808 (20.5MB)
used = 0 (0.0MB)
free = 21495808 (20.5MB)
0.0% used
To Space:
capacity = 24117248 (23.0MB)
used = 0 (0.0MB)
free = 24117248 (23.0MB)
0.0% used
#Old Space内存大小与使用率
PS Old Generation
capacity = 1610612736 (1536.0MB)
used = 37478360 (35.742149353027344MB)
free = 1573134376 (1500.2578506469727MB)
2.3269628485043845% used
27252 interned Strings occupying 3201592 bytes.
此图是问题机器的heap信息截图,单不是当时时间点的截图。
![企业微信截图_262292de-b7fc-4163-a0ef-e344918d609a.png]([object Object]&name=企业微信截图_262292de-b7fc-4163-a0ef-e344918d609a.png&originHeight=1016&originWidth=884&originalType=binary&ratio=1&size=510072&status=done&style=none&taskId=ucd109353-c487-49c7-82b6-bdbb0b092eb&width=442)
2.2.2、栈使用内存空间
栈内存不好统计,我们默认线程数量*xss就是栈使用的空间,真实的栈使用空间要小于这个值。
2.2.3、操作系统及其他可使用内存
2.2.3.1、可使用内存 = 总内存 - 应用使用内存 = 4096 - 3514 = 582M
2.2.3.2、不触发告警内存 = 可使用内存 - 200 = 582 -200 = 382M
三、运维JVM策略是否合理?
运维策略不管申请多大的内存,首先一半分配给JVM。当申请4G内存,操作系统及其他应用可使用内存为582M,不触发告警的内存为382M。
四、cpu为什么占用比较高
由于此问题在我处理问题前已经恢复,无法采集相关的日志和dump。