oracle问了我很多年的一个问题:为什么内存会越用越多

我的疑问

不知道各位有没有观察过:在数据库启动以后,内存会一直缓慢增长(废话!),但是这里有个细节。

sga的固定区域不说了。

pga的大小是个target值,正常情况下应该是结果集大的超过pga的值后,就会触发进程的收缩回收,这样就把target值控制到目标了,然后也不影响超大结果集膨胀uga的情况。这个也是常见oom的原理。

但是还有一种情况,在连接数和pga都维持在稳定状态时。内存仍然会缓慢增高,然后达到一个值以后平稳下去。这个问题一直困扰着我,不仅在数据库视图都显示正常,从系统进程上观察也都是正常的。

我的答案

我在一次case中发现了这个问题

使用top 大写M,可以看到进程的内存使用,其中free -g的物理内存使用,是通过res(又叫rss或rsz)来计算的,这个部分会有一个shr共享内存段。

我对这个shr是谁的共享段,其实一直有疑问。我在其他的环境上,很少能看到占用shr这么大的。

但是通过pmap查看进程共享段的shmid是0x1d(换10进制就是29)

通过ipcs可以看到,该共享段就是数据库的sga的共享段

因为该系统没有使用hugepage。当进程的rss越来越大,他的对应的pagetable也会变大

这里转个计算公式

速算一下,这种rss有28g的进程,他的pagetable就有60m,而且这部分内存是无法被数据库的视图监控到的!因为这是操作系统虚拟内存的映射。

当连接一直不清理的情况下,因为sql和内存地址的随机性,逐渐访问的共享内存会变多,导致持有的pagetable增大

当连接一直不清理的情况下,各个连接逐渐访问全部能访问的共享内存。会逐渐达到一个稳定的内存使用

我的思考

1、如果数据库的连接有新晨代谢,应用连接池初始值给的较小,他会在峰值后随机清理掉连接,这样就能将进程持有的页表释放掉。

2、这个pagetable因为是来自于共享内存段的虚拟地址映射,会有上限。保证操作系统的20%空闲空间可以避免这个事。

3、页表占用的内存是无法算到pga中的,这个又跟进程连接数正相关,不过hugepage倒是可以极大减少页表的大小。如果你的数据库会有极高的连接数,需要设置一些参数维持连接的新晨代谢。像是expire_time这样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值