Fix 'ORA-04031: unable to allocate bytes' in Oracle
Oracle can't allocate shared memory. Usually a shared pool issue. Quick fix: flush the pool or bump up the SGA.
Quick answer
Run ALTER SYSTEM FLUSH SHARED_POOL; from SQL*Plus. If that doesn't work, bump up SHARED_POOL_SIZE or SGA_TARGET. But flushes are a band-aid — the real fix is memory tuning.
What's going on here
You're hitting ORA-04031 when Oracle can't find a contiguous chunk of memory in the shared pool. This shows up during heavy SQL parsing, large PL/SQL blocks, or after a big batch job runs. I've seen it most often on poorly-tuned Oracle 11g and 12c databases where someone set SGA_TARGET too low and never monitored shared pool free lists. The error code is 4031. The message gives you the size it needed — that's your clue. A 64KB allocation failure means something different than a 4MB one.
The culprit here is almost always shared pool fragmentation. You've got pinned objects, large SQL cursors, or a rogue PL/SQL package that eats memory and won't let go. The shared pool works like a big slab — once it gets chopped into little pieces, Oracle can't satisfy a request for a contiguous chunk even if total free memory looks fine. Don't bother with ALTER SYSTEM SET DB_CACHE_SIZE — that's the buffer cache, not the shared pool. Different memory region.
Step-by-step fix
- Check current shared pool usage
Look for huge chunks in 'free memory' below 10% of total shared pool.SELECT pool, name, bytes/1024/1024 MB FROM v$sgastat WHERE pool = 'shared pool' ORDER BY bytes DESC; - Flush the shared pool (emergency only)
This clears all cached SQL and PL/SQL. It'll make new queries parse slower for a minute. Only do this if the error is actively blocking users.ALTER SYSTEM FLUSH SHARED_POOL; - Increase shared pool size
If you're using AMM or ASMM (SGA_TARGET), increase that instead:ALTER SYSTEM SET SHARED_POOL_SIZE = 2G SCOPE=BOTH;ALTER SYSTEM SET SGA_TARGET = 4G SCOPE=BOTH;. - Resize large pool if neededIf the error mentions 'large pool', run
ALTER SYSTEM SET LARGE_POOL_SIZE = 256M;. This helps when RMAN or parallel queries are the trigger. - Restart the instance (if above fails)
This resets all memory. Last resort — you'll lose cached plans, but it buys you time to tune.SHUTDOWN IMMEDIATE; STARTUP;
Alternative fixes if the main one fails
If increasing memory doesn't stop the error, you've got a different problem. Some things to try:
- Set CURSOR_SPACE_FOR_TIME=TRUE — forces cursor sharing. Use this only if you're sure your SQL is stable. It can cause latch contention.
- Pin large packages in memory with
DBMS_SHARED_POOL.KEEP. This prevents them from fragmenting the pool. Example:
Yes, that's a real package many miss.EXEC DBMS_SHARED_POOL.KEEP('SYS.STANDARD'); - Reduce SQL parsing — use bind variables. If your app sends literal SQL like
SELECT * FROM emp WHERE id = 100instead ofSELECT * FROM emp WHERE id = :x, you'll fragment the shared pool fast. This is the #1 cause I've seen in custom apps. - Check for memory leaks — Oracle bugs in 11.2.0.3 and 12.1.0.2 are known for this. Run
SELECT * FROM v$memory_resize_ops WHERE component='shared pool' ORDER BY time DESC;to see if memory keeps growing without shrinking.
Prevention tips
Stop the bleeding before it starts. Three things:
- Set SGA_TARGET high enough — for a busy OLTP system, start at 40% of physical RAM. Monitor
v$sgastat.free memory— if it drops below 5% of shared pool, you're in trouble. - Use automatic memory management (AMM) in 12c and later — set
MEMORY_TARGETand let Oracle handle the split between SGA and PGA. Less manual tuning, fewer errors. - Schedule shared pool flushes during maintenance windows if you can't fix the fragmentation source. A monthly
ALTER SYSTEM FLUSH SHARED_POOLat 3 AM beats a 2 AM crash. - Upgrade to Oracle 19c if you're still on 11g or 12c. The memory management in 19c is miles better. I've cut ORA-04031 incidents by 90% just by upgrading.
One last thing — don't ignore this error. I've seen people flush the shared pool every hour for months instead of fixing the real issue. That's like swapping tires on a car with a blown engine. Tune the memory or fix the SQL. Your users will thank you.
Was this solution helpful?