原创: Hollis
平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,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命令是最经常使用的命令之一。
上图中,一共有3行6列数据,行数据的意义如下: Mem 行是内存的使用情况。 -/+ buffers/cache 行是物理内存的缓存统计情况。 Swap 行是交换空间的使用情况。
前面分别介绍过了物理内存和Swap分区。这里再介绍一下buffers和cache。
buffer与cache的区别
简单点说:
buffers 就是存放要输出到disk(块设备)的数据,缓冲满了一次写,提高IO性能(内存 -> 磁盘)
cached 就是存放从disk上读出的数据,常用的缓存起来,减少IO(磁盘 -> 内存)
buffer 和 cache,两者都是RAM中的数据。简单来说,buffer是即将要被写入磁盘的,cache是被从磁盘中读出来的。
介绍完了buffer和cache的区别,接下来分析下free命令查询到的数据。
Mem行
这一行展示物理内存的整体情况。
Total:8388608。表示物理内存总大小。
Used :2926968。表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。
Free :5461640。表示未被分配的内存。
Shared:0。共享内存,一般系统不会用到。
Buffers:0。系统分配但未被使用的buffers 数量。
Cached:1654392。系统分配但未被使用的cache 数量。
-/+ buffers/cache 行
Used:1272576。 表示实际使用的buffers 与cache 总量,也是实际使用的内存总量。
Free:7116032。 未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。
Swap 行
Total:16777208。Swap内存总大小。
Used:0。表示已分配的Swap大小。
Free:16777208。表示未被分配的内存。
接下来,再来整体看一下数据。
机器上实际可用内存大小:
已经分配的内存大小:
物理内存总大小
总结一下,整个机器的总内存大小8388608,其中已经分配的内存有2926968,还未分配的内存有5461640。而分配的2926968中,有1654392还没有使用,有1272576已经用掉了。当前机器中还有7116032内存可以使用。
free命令参数
-m 以M为单位显示内存
-g 以G为单位显示内存
-s 2持续的观察内存的状况,每隔2秒打印一次
除了free ,还可以在Linux下可以使用/proc/meminfo文件查看操作系统内存的使用状态,其实,free命令的内容也是来自于/proc/meminfo文件。
top命令
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。
在前面两篇文章中介绍过使用top命令查看Load Avg和CPU利用率。top还会打印的一部分信息就是内存情况。
上面的Mem行和Swap行展示的就是内存的使用情况。并且也会按照进行展示不同进程的内存占用情况。十分好用。
Java Web应用内存占用飙高排查思路
JVM以一个进程(Process)的身份运行在Linux系统上,对于Linux来说,JVM不过是一个具有自助管理内存的乖孩子而已。
一般在应用启动时都可以通过JVM参数来设置JVM内存的大小。如果超过这个限制就会抛出异常。所以,我们比较常见的内存占用过高问题,最显著的现象就是抛出各种OutOfMemoryError。
有一种可能导致直接内存,也就是Linux的物理内存过高的情况,就是NIO的使用。NIO引入了一种基于通道与缓冲区的IO方式,他可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。
所以,在使用NIO的时候,要特别小心,避免导致机器内存被挤满。
导致JVM中内存占用飙高的原因可能有很多。最常见的就是内存泄露。
内存泄露排查思路
1、使用top命令,查看占用内存较高的进程ID。
发现PID为3331的进程占用内存 90.6%。而且是一个Java进程,基本断定是程序问题。
2、使用jmap查看内存情况,并分析是否存在内存泄露。
得到堆dump文件后,可以进行对象分析。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。
欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563
本群提供免费的学习指导 架构资料 以及免费的解答
不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导
网友评论