Oracle

獲取 ORA-04031 後調整 Java 池

  • April 20, 2020

我在 Windows 2012 RC2 上執行 Oracle 12.2.0.1 標準版。我沒有執行 Oracle 的自動記憶體管理。

我們在警報日誌中看到了這些:

ORA-04031: unable to allocate 4096 bytes of shared memory ("java pool","prv//////LBKLAGIMAAAAAAAA","JOXLE^aff7380e",":SGAClass")

我想嘗試的第一件事是刷新共享池以解決眼前的問題,而開發團隊正在修復 SQL 程式碼,所以我執行:

ALTER SYSTEM FLUSH SHARED_POOL;

直到那時我才意識到 Java 池實際上並不是共享池的一部分。所以我試著看一下Java池。

我想這告訴我我的 Java 池大約是 32MB:

SQL> select * from v$javapool;
CATEGORY                                            MEMUSED     CON_ID
------------------------------------------------ ---------- ----------
:Intern                                              973440          0
:SGAClass                                          32103240          0
:SROState                                             81120          0

我執行了這個調整工具,如果我能正確解釋的話,它說增加 Java 池大小並沒有太多好處:

   select
      estd_lc_size,
      java_pool_size_for_estimate,
      java_pool_size_factor
   from
      v$java_pool_advice;
ESTD_LC_SIZE JAVA_POOL_SIZE_FOR_ESTIMATE JAVA_POOL_SIZE_FACTOR
------------ --------------------------- ---------------------
           8                          16                    .5
          24                          32                     1
          25                          48                   1.5
          25                          64                     2
          25                          80                   2.5
          25                          96                     3
          25                         112                   3.5
          25                         128                     4
          25                         144                   4.5
          25                         160                     5
          25                         176                   5.5

我從這裡的 Oracle 文件中執行了以下查詢,它似乎表明 SGA_TARGET 值很好!

SELECT (
  (SELECT SUM(value) FROM V$SGA) -
  (SELECT CURRENT_SIZE FROM V$SGA_DYNAMIC_FREE_MEMORY)
  ) "SGA_TARGET"
FROM DUAL;
SGA_TARGET
----------
5167382528 = 4928 MB i.e. same as what it currently is!

我知道:

   MEMORY_TARGET = 0
   SGA_MAX_SIZE = 4928M
   SGA_TARGET = 4928M
   JAVA_POOL_SIZE = 0
   SHARED_POOL_SIZE = 0
   DB_CACHE_SIZE = 0 
   DB_KEEP_CACHE_SIZE = 0
   MEMORY_MAX_TARGET = 0

…所以當我們不使用 AMM 時,我有點困惑如何調整它。

那麼如何解決這個問題呢?

  1. 是增加 Java 池大小的最佳選擇嗎?
  2. 如果是這樣,不使用 AMM 時如何執行此操作?

AMM 還是 ASMM?

Oracle 數據庫實例中有兩種形式的記憶體管理:

  1. 自動記憶體管理 (AMM)
  2. 自動共享記憶體管理 (ASMM)

如果您要為 設置值,MEMORY_MAX_TARGET那麼MEMORY_TARGET您將處於 AMM 模式。您的 Oracle 實例將分配記憶體直到MEMORY_TARGET設置。如果您注意到性能影響,那麼您可以將MEMORY_TARGET值增加到MEMORY_MAX_TARGET大小,而無需重新啟動實例。

如果您還沒有為您的實例設置MEMORY_MAX_TARGETMEMORY_TARGET值,那麼我們可以假設您處於 ASMM 模式,因為您已經為SGA_TARGET參數設置了一個值。

在 ASMM 模式下,會自動配置以下參數:

表 6-2 自動調整大小的 SGA 組件及對應參數

SHARE_POOL_SIZE

LARGE_POOL_SIZE

JAVA_POOL_SIZE

DB_CACHE_SIZE

STREAMS_POOL_SIZE

參考: 表 6-2 (Oracle 文件)

還有以下小註釋表明:

除了設置SGA_TARGET為非零值之外,您還必須將表 6-2 中列出的所有初始化參數設置為零,以啟用自動調整大小的 SGA 組件的全自動調整。

因此無需將 設置為JAVA_POOL_SIZE非零值,除非您想手動為參數分配最小值。否則,Oracle 將在您的大小邊界內分配記憶體SGA_TARGET,目前略高於 4 GB ( 4928M)。

什麼在使用 SGA_TARGET?

然後有提示:

強調我的)

表 6-3中列出的手動調整大小的參數,如果已設置,則從 中獲取它們的記憶體SGA_TARGET留下可用於表 6-2 中列出的組件的內容。

表 6-3中的參數為:

LOG_BUFFER

DB_KEEP_CACHE_SIZE

DB_RECYCLE_CACHE_SIZE

DB_nK_CACHE_SIZE

參考: 表 6-3(Oracle 文件)

解決方案

如果表 6-3中的組件使用了太多記憶體,則池中沒有足夠的記憶體來自動為表 6-2中的組件或在您的情況下為參數SGA_TARGET分配足夠的記憶體。您可以觀察錯誤:JAVA_POOL_SIZE

ORA-04031: 無法分配 4096 字節的共享記憶體 (“java pool”,“prv//////LBKLAGIMAAAAAAAAA”,“JOXLE^aff7380e”,​​":SGAClass")

您可能必須將SGA_TARGET參數增加到比您目前擁有的值更高的值,以便 SGA 池有足夠的記憶體來自動調整動態參數。

嘗試8192M觀察您的 Oracle 實例如何響應這些更改。

參考閱讀

引用自:https://dba.stackexchange.com/questions/265187