出现原因:
当oracle进程向OS请求内存而无法满足时,会报出ora-4030错误,该错误表明oracle进程需要更多PGA或者UGA内存(MTS中UGA位于SGA中);
大致的诱导原因有以下几种:
1 OS的物理内存或者swap不够;过大的SGA设置或者进程太多导致内存枯竭都可引发此类问题
2 OS用户的limit设置太小(仅限UNIX)
3 Oracle bug导致的内存泄漏
解决方法
1
查看OS中是否有足够多的内存,
UNIX:使用top检查物理内存和swap使用情况;使用vmstat检查空闲的物理内存数目;swapon –s检查swap分区使用情况;
如果使用了hugepage,不合理的设置也会导致内存过度使用grep Huge /proc/meminfo
Windows:使用任务管理器检查内存使用情况
2
查看OS上是否有limit设置
UNIX:使用limit/ulimit命令查看(有时候unlimited实际上代表的是2G,最好设置成具体的数值)
Windows:每个进程的可寻址内存为2G(包含stack/PGA/UGA),可以设置增大为3G或更高
3
查看ORACLE上是否有limit设置
_PGA_MAX_SIZE:设置了一个进程可使用的PGA大小,默认为200M
通过该sql查看pga的内存数量
select sum(value)/1024/1024 Mb from v$sesstat s, v$statname n where n.STATISTIC# = s.STATISTIC# and name = 'session pga memory';
注:当系统升级至11.2后,_PGA_MAX_SIZE和PGA_AGGREGATE_TARGET都设置大于4G时,仍然可能会有ora-4030发生,由OS或者ORACLE设置的limit触发,导致map entry消耗完毕;
OS:调大vm.max_map_count值,可通过sysctl动态设置,sysctl -w vm.max_map_count=200000
ORACLE:调整realfree heap pagesize大小,默认值为64KB(65536)占有4G,可调整为256KB(262144)即16G
此问题由Bug 11852492引起
4
如果PGA使用manual方式管理,可以减小workarea的大小,比如SORT_AREA_SIZE,当进程需要更多的内存排序时则会用到temp segment,以降低性能为代价减少内存的使用。
而workarea_size_policy为AUTO时,则可通过自动调整PGA来减少ora-4030的发生
找出占有内存最多的进程
select sid,name,value from v$statname n,v$sesstat s
where n.STATISTIC# = s.STATISTIC# and name like 'session%memory%'
order by 3 asc;
可以查询v$pgastat查询目前PGA的总体使用情况
若系统中频繁出现4030错误,则可使用ALTER SYSTEM SET EVENTS '4030 trace name heapdump level 536870917;name errorstack level 3';,待到该错误再次触发时生成的dump文件包含很多信息,可以找出内存过度使用的原因。
Why does my code give ORA-4030 when run through listener connection, but not local connection?
On most unix/linux OS, for local connections, the shadow processes spawned on the database server inherit the ulimits of the OS user that starts the database.
For processes spawned through a listener connection, it is the ulimits of the OS user that starts the listener that are inherited.
Need to verify that memory related resource limits as listed by ulimit -a are set large enough to prevent the ORA-4030.
See below discussion on ulimits.
Restart the listener as OS user that has the higher ulimits in place or adjust the ulimits for the OS user that starts the listener.