美文网首页java高级开发群@IT·互联网Java 杂谈
线上服务器内存分析及问题排查

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

作者: Java技术剑 | 来源:发表于2018-08-10 16:07 被阅读16次

    原创: 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

    本群提供免费的学习指导 架构资料 以及免费的解答

    不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导

    相关文章

      网友评论

        本文标题:线上服务器内存分析及问题排查

        本文链接:https://www.haomeiwen.com/subject/tgflbftx.html