关于内存异常的一个猜想

简介: 今天查看生产某个服务器的负载的时候,发现内存的使用情况有些异常。 top - 12:00:08 up 15 days, 12:04, 13 users,  load average: 63.
今天查看生产某个服务器的负载的时候,发现内存的使用情况有些异常。
top - 12:00:08 up 15 days, 12:04, 13 users,  load average: 63.31, 55.12, 43.39
Tasks: 5542 total,  21 running, 5511 sleeping,   0 stopped,  10 zombie
Cpu(s): 13.6%us,  3.7%sy,  0.0%ni, 81.1%id,  0.1%wa,  0.3%hi,  1.2%si,  0.0%st
Mem:  363033360k total, 257187848k used, 105845512k free,  1368028k buffers
Swap: 377487328k total,        0k used, 377487328k free, 167742788k cached

这个参数在前几天可是200多G,那100多G到哪去了呢?
使用ipcs来查看共享段的情况,没有发现异常的情况。
> ipcs -a
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 500105218  root      644        80         2
0x00000000 500137988  root      644        16384      2
0x00000000 500170757  root      644        280        2
0x550002fb 500203526  root      644        256064     1                 locked
0xba17ff18 500760585  xxxxx    660        35704012800 3963
0xd9152b54 500695050  xxxxx   660        3542089728 37
0x91442618 500826123     xxxx  660        4096       0
0xdb22d1bc 500957196  xxxxxx  660        3340763136 32
使用free -m来查看剩余内容情况,剩余268913M的内容,这个和期望的结果还是一致的。
             total       used       free     shared    buffers     cached
Mem:        354524     250998     103526          0       1336     164050
-/+ buffers/cache:      85611     268913
Swap:       368639          0     368639

关于top和free的命令解释,我觉得http://blog.itpub.net/34596/viewspace-588857/这个帖子解释得很好,
free命令显示在操作系统中使用和空闲的内存数量。
Top 显示是和Linux 对内存使用的方式关系紧密,linux 尽可能的要求
使用物理内存来提高Buffer 和Cache 对Disk 的I/O操作。Linux 将尽可能多的将I/O 操作磁盘上的信息保存在内存当中,如果Oracle(其他程序也一样)需要更多的内存空间,Linux 才会将一些内存使用LRU 算法清理出来,如果不需要则继续保持这些数据信息在内存中。
尽管从这个解释来看,不是问题,从vmstat来看也没有发现swap的异常。总算松了口气,但是还是希望能够查出倒底那100多G的空间都消耗到哪了。
> vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
49  1      0 105913072 1368380 167977888    0    0  1330    81    0    0 10  3 87  0  0
525  1      0 105816848 1368380 167978320    0    0 138008 10340 40898 90606 17  6 77  0  0
22  0      0 105814304 1368380 167978544    0    0 225004  6875 37504 78706 12  5 83  0  0
 8  0      0 105782352 1368380 167978672    0    0 112008 12034 39147 86160 13  4 83  0  0
11  0      0 105787408 1368380 167978896    0    0 237008  6868 38895 84063 13  4 83  0  0


这个时候还是使用top命令  直接使用shift+M能够查看出使用内存的进程情况。
top - 13:05:54 up 15 days, 13:10, 12 users,  load average: 45.59, 48.43, 49.50
Tasks: 5451 total,   5 running, 5436 sleeping,   0 stopped,  10 zombie
Cpu(s):  7.8%us,  2.7%sy,  0.0%ni, 88.3%id,  0.1%wa,  0.1%hi,  0.9%si,  0.0%st
Mem:  363033360k total, 256454800k used, 106578560k free,  1368868k buffers
Swap: 377487328k total,        0k used, 377487328k free, 167948244k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
16422 oraaems2  15   0 6399m 5.3g 5.3g S  0.0  1.5   4:16.15 ora_dbw1_AEM02
16426 oraaems2  15   0 6399m 5.3g 5.2g S  0.0  1.5   4:08.93 ora_dbw3_AEM02
16424 oraaems2  15   0 6399m 5.2g 5.2g S  0.0  1.5   4:09.52 ora_dbw2_AEM02
16419 oraaems2  15   0 6399m 5.2g 5.2g S  0.0  1.5   4:06.01 ora_dbw0_AEM02
26885 oraaems2  15   0 6394m 3.9g 3.9g S  0.0  1.1   7:01.84 oracleAEM02 (LOCAL=NO)
 9779 oraaems2  16   0 6392m 3.8g 3.8g S  0.0  1.1   3:36.58 oracleAEM02 (LOCAL=NO)
26535 oraaems2  15   0 6394m 3.5g 3.5g S  0.0  1.0   7:26.10 oracleAEM02 (LOCAL=NO)
 5825 oraaems2  15   0 6394m 3.5g 3.5g S  0.0  1.0   4:29.41 oracleAEM02 (LOCAL=NO)
26932 oraaems2  15   0 6394m 3.4g 3.4g S  0.0  1.0   5:46.79 oracleAEM02 (LOCAL=NO)
 5882 oraaems2  15   0 6394m 3.4g 3.4g S  0.0  1.0   3:55.93 oracleAEM02 (LOCAL=NO)
26479 oraaems2  15   0 6394m 3.4g 3.4g S  0.0  1.0   6:43.21 oracleAEM02 (LOCAL=NO)
25670 oraaems2  15   0 6394m 3.3g 3.3g S  0.0  1.0   6:00.96 oracleAEM02 (LOCAL=NO)
28928 oraaems2  15   0 6394m 3.3g 3.3g S  0.0  0.9   3:05.69 oracleAEM02 (LOCAL=NO)
 5792 oraaems2  15   0 6394m 3.1g 3.1g S  0.0  0.9   4:42.41 oracleAEM02 (LOCAL=NO)
29874 oraaems2  15   0 6394m 2.9g 2.9g S  0.0  0.8   2:20.13 oracleAEM02 (LOCAL=NO)
 1964 oraaems2  15   0 6398m 2.8g 2.8g S  0.0  0.8   1:16.83 oracleAEM02 (LOCAL=NO)
 1954 oraaems2  15   0 6394m 2.7g 2.7g S  0.0  0.8   0:54.40 oracleAEM02 (LOCAL=NO)
 5788 oraaems2  15   0 6394m 2.6g 2.6g S  0.0  0.8   3:26.67 oracleAEM02 (LOCAL=NO)
 1970 oraaems2  15   0 6394m 2.5g 2.5g S  0.0  0.7   0:37.69 oracleAEM02 (LOCAL=NO)
16435 oraaems2  15   0 6393m 1.9g 1.9g S  0.0  0.6   1:29.38 ora_smon_AEM02
 5816 oraaems2  15   0 6394m 1.9g 1.8g S  0.0  0.5   2:35.20 oracleAEM02 (LOCAL=NO)
24344 oraaems2  15   0 6389m 1.6g 1.6g S  0.0  0.5   0:03.12 oracleAEM02 (LOCAL=NO)
 5790 oraaems2  16   0 6394m 1.3g 1.3g S  0.0  0.4   0:47.47 oracleAEM02 (LOCAL=NO)
16417 oraaems2  15   0 6386m 1.2g 1.2g S  0.0  0.4   0:21.68 ora_mman_AEM02
24323 oraaems2  15   0 6389m 1.2g 1.2g S  0.0  0.3   2:02.72 oracleAEM02 (LOCAL=NO)
 1962 oraaems2  15   0 6394m 1.2g 1.2g S  0.0  0.3   0:41.28 oracleAEM02 (LOCAL=NO)
 1958 oraaems2  15   0 6394m 1.1g 1.1g S  0.0  0.3   0:39.05 oracleAEM02 (LOCAL=NO)
22982 oraaems2  15   0 6393m 814m 807m S  0.0  0.2   2:24.63 ora_cjq0_AEM02
18024 oraaems2  15   0 6393m 599m 592m S  0.9  0.2  74:31.45 oracleAEM02 (LOCAL=NO)

能够看到进程的内存消耗都集中在AEM02这个库上,这个库其实是一个很小的库,SGA的设置只有6G,怎么内存消耗这么大呢。
首先查看数据库日志,没有相关的警告和错误。从启动开始,负载都很小。发现了一句比较奇怪的日志,但是hugapage的部分没有报错。
Starting ORACLE instance (normal)
****************** Huge Pages Information *****************
Huge Pages memory pool detected (total: 30000 free: 16509)
DFLT Huge Pages allocation successful (allocated: 0)
***********************************************************
然后查看了下sga的设置。发现sga_target设置为了0,同时shared_pool_size,db_cache_size也都是0,这个从配置来说也确实是个问题。
因为负载很小,就在线做了修改,观察了一下数据库的内存使用情况,还是没有任何的改变。
排除了shared_pool_size和db_cache_size的影响,注意力都集中在了启动日志的那句话上" DFLT Huge Pages allocation successful (allocated: 0)"

为什么hugepage可用,但是没有分配呢。查看其它的实例启动情况都使用到了hugepage。
最后能够想到的只能是11g中的新参数memory_target了。
一查看发现还真是,memory自动管理启动之后,hugep page就不会启用了,这也就是为什么日志中huge page allocation 为0的原因了。

SQL> show parameter memory
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
hi_shared_memory_address             integer     0
memory_max_target                    big integer 16016M
memory_target                        big integer 16016M
shared_memory_address                integer     0

但是这个和那100G的内存关系大吗,我使用top 把AEM02内存使用第一页的进程情况作了统计,发现已经占用了85G的内存资源,基本能够说明问题了。
明白了这一点再来看ipcs的结果就能够理解一些数据的意义了。
> ipcs -a
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 500105218  root      644        80         2
0x00000000 500137988  root      644        16384      2
0x00000000 500170757  root      644        280        2
0x550002fb 500203526  root      644        256064     1                 locked
0xba17ff18 500760585  xxxxx    660        35704012800 3963
0xd9152b54 500695050  xxxxx   660        3542089728 37
0x91442618 500826123     aems2  660        4096       0
0xdb22d1bc 500957196  xxxxxx  660        3340763136 32

但是memory_target的修改和参数memory_max_target是关联的,无法在线修改,而且在生产中也不适宜做这样大胆的尝试,所以以上的分析只能说是一个猜想,只能静静等待下一次实例重启的机会来验证这个判断了。




相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
目录
相关文章
|
存储 缓存 算法
深入浅出JVM(二)之运行时数据区和内存溢出异常
深入浅出JVM(二)之运行时数据区和内存溢出异常
|
Kubernetes Java API
|
存储 Java 编译器
Java内存区域与内存溢出异常 - 运行时数据区
【8月更文挑战第2天】Java运行时数据区包括:1) 程序计数器:记录线程执行字节码的行号,线程私有;2) Java虚拟机栈:描述方法执行的内存模型,线程私有,深度过大抛出`StackOverflowError`;3) 本地方法栈:服务于Native方法,线程私有;4) Java堆:所有线程共享,对象实例在此分配内存;5) 方法区:存储类信息、常量等数据;6) 运行时常量池:方法区的一部分,存放字面量和符号引用。不当使用如无限创建对象或过度递归调用会导致各种内存溢出错误。
118 1
|
Arthas 存储 监控
JVM内存问题之JNI内存泄漏没有关联的异常类型吗
JVM内存问题之JNI内存泄漏没有关联的异常类型吗
155 1
|
Java C++
Java内存区域于内存溢出异常
这篇文章详细解释了Java虚拟机的内存区域划分、各区域的作用以及可能遇到的内存溢出异常情况。
166 0
|
缓存 算法 Java
JVM内存溢出(OutOfMemory)异常排查与解决方法
JVM内存溢出(OutOfMemory)异常排查与解决方法
|
测试技术 API Android开发
autox.js如何监听异常情况,比如网络中断、内存慢、应用死机或者页面无响应
autox.js如何监听异常情况,比如网络中断、内存慢、应用死机或者页面无响应
dispatch_after引起的内存释放异常闪退
dispatch_after引起的内存释放异常闪退
201 0
|
C++
C++多线程场景中的变量提前释放导致栈内存异常
C++多线程场景中的变量提前释放导致栈内存异常
210 0
|
存储 算法 Java
JVM-01Java内存区域与内存溢出异常(上)【运行时区域数据】
JVM-01Java内存区域与内存溢出异常(上)【运行时区域数据】
144 0