转载自  线上服务器内存分析及问题排查

平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load、cpu、mem、qps、rt等。每个指标都有其独特的意义,很多时候在线上出现问题时,往往会伴随着某些指标的异常。大部分情况下,在问题发生之前,某些指标就会提前有异常显示。

在第一篇文章中,我们介绍了一个重要的指标就是负载(Load),其中我们提到Linux的负载高,主要是由于CPU使用、内存使用、IO消耗三部分构成。任意一项使用过多,都将导致服务器负载的急剧攀升。本文是该系列的第三篇,来分析一下影响机器负载的几个原因中的第二项,内存使用。

什么是内存

内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。

内存(Memory)也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。

物理内存

物理内存指通过物理内存条而获得的内存空间。即随机存取存储器(random access memory,RAM),是与CPU直接交换数据的内部存储器,也叫主存(内存)。

虚拟内存

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换(也就是说,当物理内存不足时,可能会借用硬盘空间来充当内存使用)。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。

Swap分区

Swap分区(即交换区)在系统的物理内存不够用的时候,把硬盘空间中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap分区中,等到那些程序要运行时,再从Swap分区中恢复保存的数据到内存中。

程序运行时的数据加载,线程并发,I/O缓冲等等,都依赖于内存,可用内存的大小,决定了程序是否能正常运行以及运行的性能。

查看内存使用情况

在Linux机器上,有多个命令都可以查看机器的内存信息。其中包括free、top等。

free命令

free命令可以显示Linux系统中空闲的、已用的物理内存swap分区以及被内核缓冲区内存。在Linux系统监控的工具中,free命令是最经常使用的命令之一。

$freetotal       used       free     shared    buffers     cached
Mem:       8388608    2926968    5461640          0          0    1654392
-/+ buffers/cache:    1272576    7116032
Swap:     16777208          0   16777208

上图中,一共有3行6列数据,行数据的意义如下: Mem 行是内存的使用情况。 -/+ buffers/cache 行是物理内存的缓存统计情况。 Swap 行是交换空间的使用情况。

前面分别介绍过了物理内存和Swap分区。这里再介绍一下buffers和cache。

buffer与cache的区别

A buffer is something that has yet to be "written" to disk.

A cache is something that has been "read" from the disk and stored for later use.

简单点说:

buffers 就是存放要输出到disk(块设备)的数据,缓冲满了一次写,提高IO性能(内存 -> 磁盘)

cached 就是存放从disk上读出的数据,常用的缓存起来,减少IO(磁盘 -> 内存)

buffer 和 cache,两者都是RAM中的数据。简单来说,buffer是即将要被写入磁盘的,cache是被从磁盘中读出来的。

介绍完了buffer和cache的区别,接下来分析下free命令查询到的数据。

Mem行

             total       used       free     shared    buffers     cached
Mem:       8388608    2926968    5461640          0          0    1654392

这一行展示物理内存的整体情况。

Total:8388608。表示物理内存总大小。

Used :2926968。表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。

Free :5461640。表示未被分配的内存。

Shared:0。共享内存,一般系统不会用到。

Buffers:0。系统分配但未被使用的buffers 数量。

Cached:1654392。系统分配但未被使用的cache 数量。

total(Mem) = used(Mem) + free(Mem)

-/+ buffers/cache 行

             total       used       free     shared    buffers     cached
-/+ buffers/cache:    1272576    7116032

Used:1272576。 表示实际使用的buffers 与cache 总量,也是实际使用的内存总量。

Free:7116032。 未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。

used(-/+ buffers/cache) = used(Mem) - cached(Mem) - buffers(Mem)

free(-/+ buffers/cache) = free(Mem) + cached (Mem)+ buffers(Mem)

Swap 行

$freetotal       used       free     shared    buffers     cached
Swap:     16777208          0   16777208

Total:16777208。Swap内存总大小。

Used:0。表示已分配的Swap大小。

Free:16777208。表示未被分配的内存。

接下来,再来整体看一下数据

$freetotal       used       free     shared    buffers     cached
Mem:       8388608    2926968    5461640          0          0    1654392
-/+ buffers/cache:    1272576    7116032
Swap:     16777208          0   16777208

机器上实际可用内存大小:

   Free(-/+ buffers/cache)= Free(Mem)+buffers(Mem)+Cached(Mem);7116032 = 5461640 + 0+ 1654392

已经分配的内存大小:

   Used(Mem) = Used(-/+ buffers/cache)+ buffers(Mem) + Cached(Mem)2926968 = 1272576 + 0 + 1654392

物理内存总大小

   total(Mem) = used(-/+ buffers/cache) + free(-/+ buffers/cache)8388608 = 1272576 + 7116032

总结一下,整个机器的总内存大小8388608,其中已经分配的内存有2926968,还未分配的内存有5461640。而分配的2926968中,有1654392还没有使用,有1272576已经用掉了。当前机器中还有7116032内存可以使用。

free命令参数

-m 以M为单位显示内存

$free -mtotal       used       free     shared    buffers     cached
Mem:          8192       2802       5389          0          0       1559
-/+ buffers/cache:       1243       6948
Swap:        16383          0      16383

-g 以G为单位显示内存

$free -gtotal       used       free     shared    buffers     cached
Mem:          8          2          5         0         0           1
-/+ buffers/cache:       1          6
Swap:        16          0          16

-s 2持续的观察内存的状况,每隔2秒打印一次

$free -s 2total       used       free     shared    buffers     cached
Mem:       8388608    2873128    5515480          0          0    1600588
-/+ buffers/cache:    1272540    7116068
Swap:     16777208          0   16777208total       used       free     shared    buffers     cached
Mem:       8388608    2873168    5515440          0          0    1600628
-/+ buffers/cache:    1272540    7116068
Swap:     16777208          0   16777208

除了free ,还可以在Linux下可以使用/proc/meminfo文件查看操作系统内存的使用状态,其实,free命令的内容也是来自于/proc/meminfo文件。

top命令

top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。

在前面两篇文章中介绍过使用top命令查看Load Avg和CPU利用率。top还会打印的一部分信息就是内存情况。

top - 17:49:32 up 2 days,  6:25,  1 user,  load average: 0.01, 0.09, 0.12
Tasks:  30 total,   1 running,  29 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.1%us,  0.0%sy,  0.0%ni, 88.0%id,  3.8%wa,  0.0%hi,  0.0%si,  8.1%st
Mem:   8388608k total,  2884716k used,  5503892k free,        0k buffers
Swap: 16777208k total,        0k used, 16777208k free,  1612080k cachedPID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND85690 admin     20   0 5138m 1.1g  47m S  2.3 13.9  93:28.92 java

上面的Mem行和Swap行展示的就是内存的使用情况。并且也会按照进行展示不同进程的内存占用情况。十分好用。

Java Web应用内存占用飙高排查思路

JVM以一个进程(Process)的身份运行在Linux系统上,对于Linux来说,JVM不过是一个具有自助管理内存的乖孩子而已。

一般在应用启动时都可以通过JVM参数来设置JVM内存的大小。如果超过这个限制就会抛出异常。所以,我们比较常见的内存占用过高问题,最显著的现象就是抛出各种OutOfMemoryError。

有一种可能导致直接内存,也就是Linux的物理内存过高的情况,就是NIO的使用。NIO引入了一种基于通道与缓冲区的IO方式,他可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。

所以,在使用NIO的时候,要特别小心,避免导致机器内存被挤满。

导致JVM中内存占用飙高的原因可能有很多。最常见的就是内存泄露。

内存泄露排查思路

1、使用top命令,查看占用内存较高的进程ID。

➜  ~ topPID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
3331 admin     20   0 7127m 2.6g  38m S 10.7 90.6  10:20.26 java

发现PID为3331的进程占用内存 90.6%。而且是一个Java进程,基本断定是程序问题。

2、使用jmap查看内存情况,并分析是否存在内存泄露。

jmap -heap 3331:查看java 堆(heap)使用情况jmap -histo 3331:查看堆内存(histogram)中的对象数量及大小jmap -histo:live 3331:JVM会先触发gc,然后再统计信息jmap -dump:format=b,file=heapDump 3331:将内存使用的详细情况输出到文件

得到堆dump文件后,可以进行对象分析。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。

线上服务器内存分析及问题排查相关推荐

  1. 服务器性能指标(二)-- 线上服务器内存分析及问题排查

    服务器性能指标(二)-- 线上服务器内存分析及问题排查 平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load.cpu.mem.qps.rt等.每个指标都有其独特的意义,很多时候在线上出现 ...

  2. 线上服务器内存飙升怎么排查?

    一.线上服务器内存飙升怎么排查? 1.通过top命令查看cpu.内存占用情况 2.通过shift+m命令按内存占用排序查看哪个java进程占用内存高,获取pid 3.通过jmap -histo pid ...

  3. window服务器cpu过高的排查_线上服务器发生CPU占用率过高应该如何排查并定位问题?...

    国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下: 排名前几的比较受重视的能力分别为:解决问题 ...

  4. 原创|面试官:线上服务器CPU占用率高如何排查定位问题?

    国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下: 排名前几的比较受重视的能力分别为:解决问题 ...

  5. 面试官:线上服务器CPU占用率高如何排查定位问题?

    开发十年,就只剩下这套架构体系了!! 国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下:  ...

  6. 线上服务器CPU占用率高如何排查定位问题?

    (关联着看看这篇文章:https://blog.csdn.net/u011277123/article/details/103768939) 解决问题的能力以超高比例排名第一,这也是为什么很多面试过程 ...

  7. 服务器定位cpu高占用率代码php,面试官:线上服务器CPU占用率高如何排查定位问题?,...

    面试官:线上服务器CPU占用率高如何排查定位问题?, 国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果 ...

  8. 内存地址 哪个程序_记一次排查线上程序内存的忽高忽低,又是大集合惹祸了...

    一:背景 1. 讲故事 昨天继续还技术债,优化一轮后的程序拉到线上后内存继续忽高忽低,低的时候20G,高的时候30G,过了一会又下降了几个G,毫无疑问,程序中有什么集合或者什么操作占用了大量内存,所以 ...

  9. 记一次排查线上程序内存的忽高忽低,又是大集合惹祸了

    一:背景 1. 讲故事 昨天继续还技术债,优化一轮后的程序拉到线上后内存继续忽高忽低,低的时候20G,高的时候30G,过了一会又下降了几个G,毫无疑问,程序中有什么集合或者什么操作占用了大量内存,所以 ...

最新文章

  1. 长见识!居然还有程序员考公指南这种东西?
  2. qt修改程序图标名称_解决Qt应用程序添加icon图标,修改窗口图标以及添加系统托盘问题...
  3. hibernate连接数据库配置
  4. 动态规划java LCS_动态规划递归求解LCS长度 | 学步园
  5. 从零开始,DIY一个jQuery(2)
  6. Ajax 浏览器跨域访问控制
  7. linux运维常见网络协议含义及端口
  8. SpringMVC读取资源文件的几种方式
  9. 检测目标程序ELF bit是32还是64
  10. 基于ftp4j的FTP客户端工具
  11. Android app跳转QQ加人聊天或者加群
  12. Office EXCEL如何批量把以文本形式存储的数字转换为数字
  13. 如何安装redis和给wordpres加速?
  14. 2022年茶艺师(初级)考试题库及茶艺师(初级)作业考试题库
  15. 软件测试外包干了4年,感觉废了..
  16. python conda安装
  17. 自己动手实现音乐播放器app
  18. 广告联盟反作弊一些常识
  19. 关于eXtremeDB连接问题
  20. 做人与处世:永恒的人生哲学(让你日臻成熟的50条哲理)

热门文章

  1. 算法设计与分析——贪心算法——最优装载问题
  2. 浅谈前端路由原理hash和history
  3. 了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化
  4. [SpringBoot2]错误处理_默认规则
  5. [数据结构]对称矩阵和三角矩阵压缩公式
  6. 深圳本次核酸检普筛怎么将个人信息和结果对应上??
  7. caffe安装常见问题
  8. P6810 「MCOI-02」Convex Hull 凸包
  9. 2021牛客暑期多校训练营3 C Minimum grid 网络流 + 二分图匹配
  10. hdu 6899 Xor 数位dp