Oracle sessions are dying at random. Users report sudden disconnects with no application-side explanation. There is no ORA- error returned to the client, no blocking session, no lock chain. The sessions simply vanish. In dmesg or journalctl -k you find the evidence: Out of memory: Kill process <pid> (oracle...).

The root cause: Oracle’s combined memory footprint exceeds physical RAM. The SGA (ideally pinned in hugepages), aggregate PGA across all dedicated server processes, and OS overhead push the system past available memory. The Linux OOM killer does not understand Oracle’s internal memory model. It ranks processes by memory consumption and kills the highest-scoring victim. Oracle server processes score high because they map the SGA and carry their own PGA, so they die first.

This failure mode is dangerous because the OOM killer can target any Oracle process. If it kills a critical background process such as DBWn, LGWR, PMON, or SMON, the instance can crash. Foreground-only kills cause random session deaths that look like network problems and send engineers down the wrong diagnostic path for hours.

What this means

Oracle on Linux is a multi-process architecture. The SGA is a shared memory region allocated at startup and held for the life of the instance. PGA is private memory allocated to each dedicated server process for sorting, hashing, and session state.

The Linux kernel accounts for memory per-process. It does not know that the SGA is shared across dozens of processes. It does not know about PGA_AGGREGATE_TARGET (a soft target) or PGA_AGGREGATE_LIMIT (a hard limit, introduced in 12c). When total system memory pressure exceeds a threshold, the OOM killer picks a victim based on its oom score, which is heavily influenced by the process’s resident set size.

Oracle processes score high because they map the SGA into their address space and carry their own PGA allocations. Without hugepages, the situation is worse: each process’s page table entries for the SGA consume additional kernel memory, sometimes gigabytes for large SGAs.

Oracle’s memory limits are advisory to the database but invisible to the kernel. PGA_AGGREGATE_LIMIT can prevent sessions from allocating more PGA by raising ORA-04036, but it does not prevent the kernel from killing processes when the system as a whole runs out of RAM.

flowchart TD
    A["SGA in hugepages, fixed allocation"] --> E["Physical RAM exhausted"]
    B["PGA aggregate grows: sorts, hash joins, leaks"] --> E
    C["OS and co-located processes"] --> E
    E --> F["OOM killer selects target"]
    F --> G["Oracle server process killed"]
    G --> H["User session disconnects"]
    F --> I["Background process killed: crash risk"]

Common causes

CauseWhat it looks likeFirst thing to check
SGA + PGA exceed physical RAMOOM kills in dmesg targeting oracle PIDs; random session drops`dmesg
HugePages not configuredPage table overhead consuming additional memory; SGA mapped via regular 4K pagesgrep -i huge /proc/meminfo; check HugePages_Total
AMM (MEMORY_TARGET) on LinuxSGA allocated via /dev/shm instead of hugepages; incompatible with HugePagesCheck memory_target in V$PARAMETER
PGA leak or runaway querySingle process PGA growing without bound; over allocation count rising in V$PGASTATV$PROCESS.PGA_MAX_MEM ordered descending
Co-located processes consuming RAMBackups, monitoring agents, or other databases on the same host`ps aux –sort=-%mem

Quick checks

All commands below are read-only.

# Confirm OOM killer is targeting Oracle processes
# dmesg ring buffer may have rotated on busy systems; use journalctl for persistent logs
dmesg | grep -i "out of memory\|oom"
journalctl -k | grep -i "out of memory\|oom"
# Check hugepages configuration
grep -i huge /proc/meminfo
# Check available physical memory
free -h
# Check oom_score of the PMON process (requires ORACLE_SID exported)
cat /proc/$(pgrep -f "ora_pmon_$ORACLE_SID")/oom_score
# Check page table size for the PMON process (requires ORACLE_SID exported)
cat /proc/$(pgrep -f "ora_pmon_$ORACLE_SID")/status | grep VmPTE
-- Check Oracle memory parameters
SELECT NAME, VALUE FROM V$PARAMETER
WHERE NAME IN ('sga_target', 'sga_max_size', 'pga_aggregate_target',
               'pga_aggregate_limit', 'memory_target', 'memory_max_target',
               'use_large_pages');
-- Check PGA utilization and limits
SELECT NAME, VALUE/1048576 AS mb FROM V$PGASTAT
WHERE NAME IN ('aggregate PGA target parameter',
               'total PGA inuse', 'total PGA allocated',
               'maximum PGA allocated', 'over allocation count',
               'cache hit percentage');
-- Top PGA consumers by process
SELECT SPID, PGA_ALLOC_MEM/1048576 AS pga_alloc_mb,
       PGA_MAX_MEM/1048576 AS pga_max_mb
FROM V$PROCESS
ORDER BY PGA_ALLOC_MEM DESC
FETCH FIRST 10 ROWS ONLY;  -- 12c+; use ROWNUM <= 10 on 11g
# Check alert log for OOM-related errors
adrci exec="show alert -tail 100"

How to diagnose it

  1. Confirm the OOM killer fired. Run dmesg | grep -i "out of memory\|oom" or journalctl -k | grep -i oom. Look for entries that name Oracle processes. The process name typically contains oracle or the ORACLE_SID. If you find none, the session deaths may have a different cause: network drops, OS process limits, or Oracle’s own PGA_AGGREGATE_LIMIT raising ORA-04036.

  2. Quantify the memory budget gap. Compare SGA_TARGET (or SGA_MAX_SIZE) plus PGA_AGGREGATE_TARGET against physical RAM. Leave at least 20% for OS, filesystem cache, and co-located processes. If SGA plus PGA target is close to or exceeds physical RAM, the OOM killer is inevitable under load.

  3. Verify hugepages. Check /proc/meminfo for HugePages_Total and HugePages_Free. If HugePages_Total is 0, the SGA is using regular 4K pages, and page table overhead is silently consuming additional memory. Check the use_large_pages parameter in V$PARAMETER.

  4. Identify the PGA pressure source. Query V$PGASTAT for total PGA allocated versus aggregate PGA target parameter. If total PGA allocated exceeds the target, Oracle is over-allocating. Check over allocation count: if it is growing, sessions are consuming more PGA than Oracle intended. Query V$PROCESS ordered by PGA_ALLOC_MEM to find the top consumers. A single process consuming several GB of PGA may indicate a runaway sort, hash join, or a PL/SQL collection growing without bounds.

  5. Check for AMM misconfiguration. If memory_target is set, Oracle uses Automatic Memory Management (AMM), which allocates SGA via /dev/shm instead of hugepages. AMM and HugePages are incompatible. ASMM (sga_target) with manual PGA management is the standard production configuration on Linux.

  6. Rule out non-Oracle memory consumers. Run ps aux --sort=-%mem | head -20 to see what else is consuming memory. Co-located databases, RMAN backups, monitoring agents, or JVMs can push the system over the edge.

Metrics and signals to monitor

SignalWhy it mattersWarning sign
dmesg/journalctl OOM entriesDirect evidence the kernel killed an Oracle processAny entry naming an oracle PID
total PGA allocated (V$PGASTAT)Aggregate PGA consumption across all sessionsExceeds PGA_AGGREGATE_TARGET or approaching PGA_AGGREGATE_LIMIT
over allocation count (V$PGASTAT)Oracle is allocating PGA beyond its soft targetGrowing counter
HugePages_Total (/proc/meminfo)Whether hugepages are configured at all0 means SGA uses 4K pages
Per-process PGA_MAX_MEM (V$PROCESS)Detects PGA leaks or runaway queriesSingle process with monotonically growing PGA
OS MemAvailable (/proc/meminfo)Actual RAM available including reclaimable cacheTrending toward zero

Fixes

Reduce PGA consumption

The most immediate lever is PGA_AGGREGATE_LIMIT. If it is unset or too high, set it to a value that, combined with SGA and OS overhead, stays safely below physical RAM. If the default is too permissive for your hardware, set it explicitly.

Lowering PGA_AGGREGATE_TARGET causes Oracle to manage PGA more aggressively, spilling sorts and hash joins to temp tablespace sooner. This trades query performance for memory safety. It is a better tradeoff than random session kills.

If a specific process is consuming excessive PGA (a PL/SQL collection leak or an unbounded sort), killing that session resolves the immediate pressure. Investigate the SQL or PL/SQL to prevent recurrence.

Ensure SGA uses hugepages

Without hugepages, each Oracle server process carries page table entries for the entire SGA. For large SGAs, page table overhead can consume significant additional kernel memory that is invisible to Oracle’s memory views.

Configure hugepages by setting vm.nr_hugepages in /etc/sysctl.conf to cover the SGA size. Each hugepage is 2 MB on most x86_64 Linux distributions. Set use_large_pages to ONLY to force the instance to fail startup if insufficient hugepages are available. Setting ONLY makes misconfiguration obvious at startup rather than allowing a silent fallback to 4K pages.

The memlock ulimit for the Oracle OS user must be set high enough to lock the hugepages into memory.

Reboot after changing vm.nr_hugepages if memory is fragmented, as the allocation may fail silently on a running system.

Disable AMM if using MEMORY_TARGET

If memory_target is set, Oracle uses AMM, which allocates SGA via POSIX shared memory (/dev/shm) instead of hugepages. AMM and HugePages are incompatible. To switch from AMM to ASMM plus manual PGA management:

  1. Set sga_target and pga_aggregate_target to explicit values.
  2. Unset memory_target and memory_max_target.
  3. Restart the instance.

Requires a restart. Validate in a non-production environment first.

Protect critical processes (last resort, with caveats)

Setting oom_score_adj to -1000 (or the older oom_adj to -17) makes a process immune to the OOM killer. This can protect critical Oracle background processes. However, if the system genuinely runs out of memory and the OOM killer cannot kill the protected process, the kernel may panic or kill other processes instead. This buys time but does not solve the underlying memory budget problem. Fix the memory budget first.

Prevention

  • Budget memory explicitly. Ensure SGA_TARGET plus PGA_AGGREGATE_TARGET plus OS overhead plus co-located processes stay below 80% of physical RAM.
  • Set PGA_AGGREGATE_LIMIT explicitly. Do not rely on the default if your hardware or workload does not match the formula assumptions.
  • Verify hugepages after every restart. Check /proc/meminfo for HugePages_Free and the alert log for messages about hugepage allocation failures.
  • Monitor over allocation count in V$PGASTAT. A growing counter means PGA pressure is building before it becomes an OOM event.
  • Watch per-process PGA_MAX_MEM. A process whose PGA grows monotonically over its session lifetime has a leak. Alert when any process exceeds a threshold appropriate for your workload.
  • Keep Oracle off hosts with unpredictable co-tenants. RMAN backups, JVM application servers, and monitoring agents on the same host create memory pressure spikes that are invisible to Oracle-only monitoring.

Monitoring with Netdata

When the Netdata Oracle collector runs alongside OS metrics, you can correlate database-level memory with kernel-level pressure:

  • Per-second OS memory metrics: MemAvailable, MemFree, swap usage, and hugepage utilization collected every second, so you can see the memory cliff approaching before the OOM killer fires.
  • Per-process RSS tracking: surfaces per-process memory consumption, making it obvious when Oracle processes or co-located applications consume disproportionate RAM.
  • OOM kill event detection: detects kernel OOM kills in real time and correlates them with memory pressure trends, so you do not have to grep dmesg after the fact.
  • Oracle integration signals: PGA utilization, SGA component sizes, and session counts from V$PGASTAT and related views collected alongside OS metrics.

For setup, see Oracle Database monitoring with Netdata.