Java_pool_size maior do que o valor definido

Recentemente, em uma atividade de redimensionamento de memória de um ambiente Oracle SE 11.2.0.4 utilizando gerenciamento manual de memória (mais informações sobre esta forma de gerenciamento), percebi que apesar de ter definido o valor do parâmetro java_pool_size para 256MB,  após realizar um restart da instância e realizar uma consulta para validação, o Oracle havia definido um valor de 3584MB.
Mas de como que esse valor foi definido? Porque foi setado 3584MB ao invés dos 256MB definidos inicialmente?

Vamos as evidências... Abaixo tenho os valores da SGA e do parâmetro java_pool_size que haviam sido definidos inicialmente.
--Valores definidos
sga_target     = 165G
java_pool_size = 256M
Verificando o alertlog, é possível constatar que o Oracle definiu um valor diferente para a java_pool_size quando o restart foi executado.
--Trecho do alertlog
[oracle@sipabd13 dbs]$ vi /oraprd01/app/oracle/diag/rdbms/dbprod/dbprod1/trace/alert_dbprod1.log
Release:        2.6.39-400.214.3.el6uek.x86_64
Version:        #1 SMP Thu Feb 13 17:08:24 PST 2014
Machine:        x86_64
Using parameter settings in server-side pfile /oraprd01/app/oracle/product/11.2.0/db/dbs/initdbprod1.ora
System parameters with non-default values:
  processes                = 3000
  sessions                 = 4544
  resource_limit           = TRUE
  sga_max_size             = 169472M
  use_large_pages          = "ONLY"
  _realfree_heap_pagesize_hint= 256K
  _use_realfree_heap       = TRUE
  shared_pool_size         = 57G
  large_pool_size          = 3584M
  java_pool_size           = 3584M
  streams_pool_size        = 512M
Este comportamento pode ser observado apenas a partir das versão 11.2.0.4 quando java pool é requerido durante o startup do database.  ocorre devido a granularidade (para mais informações verificar  Doc ID 947152.1), que está diretamente relacionada ao tamanho da SGA e ao numero de sub-pools.
Na tabela abaixo, o valor do granule size de acordo com o tamanho da SGA alocada.
RDBMSSGA_MAX_SIZE (or memory_max_target)GRANULE SIZE
9.2<= 128MB4MB
> 128MB16MB
10.2<= 1GB4MB
> 1GB16MB
11gR1<= 1GB4MB
>1Gb   <= 4GB16MB
>4Gb   <= 16GB64MB
>16Gb <= 64GB256MB
> 64GB512MB
11gR2 (and 11gR1 with patch  8813366 applied *) and later<= 1Gb4Mb
>1Gb   <= 8Gb16MB
>8Gb   <= 16Gb32MB
>16Gb <= 32Gb64MB
>32Gb <= 64Gb128MB
>64Gb <= 128Gb256MB
> 128Gb512MB
Vale destacar que além do java pool, a shared pool, buffer cache, redo log buffer, streams pool e large pool são dimensionadas baseando-se na granularidade.

Para definir o valor mínimo para o java pool, além da granularidade, devemos levar em consideração o número de sub-pools.
Os sub-pools são definidos baseando-se em 2 fatores e tem como máximo o número de 7 sub-pools:

  • (A)Tamanho da SGA: O Oracle aloca 1 subpool para cada 256MB - Limitado ao máximo de 7 sub-pools.
  • (B)Numero de CPUs: O Oracle aloca 1 subpool para cada 4 CPUs - Limitado ao máximo de 7 sub-pools.
A formula para definição do número de sub-pools é o valor mínimo de A ou B (min(A, B)).
De posse da quantidade de sub-pools e da granularidade, podemos definir o valor do java pool através da fórmula: min java pool = <numero de sub-pools> x <granularidade>.

No meu caso a memória alocada para a SGA foi de 165GB, desta forma a granularidade será de 512Mb e uma quantidade de 7 sub-pools (valor máximo baseado na SGA). Considerando a quantidade de CPU's (meu ambiente tinha 32) tenho uma quantidade de 7 sub-pools (valor máximo baseado na quantidade de CPU's).

Colocando os valores na fórmula para cálculo do java pool teremos um valor mínimo de 3584MB (7 x 512MB = 3584MB)

Conforme a doc 947152.1, existe uma forma de forçar uma redução do numero de sub-pools e consequentemente do valor mínimo do java pool. Porém o impacto desta alteração não pode ser confirmado pela Oracle e precisa ser validado de ambiente para ambiente.

A partir da versão 12.2, existirá um novo parâmetro oculto chamado "_force_java_pool_zero" que estando definido para true forçará o java pool a usar 0 bytes.
 "_force_java_pool_zero" = true
Para versões anteriores (11.2.0.4 e 12.1.0.n), é possível através da aplicação do Patch:20681008, definir um novo parâmetro chamado  "_bug20681008_force_java_pool_zero", que também forçará o java pool a utilizar 0 bytes.
 "_bug20681008_force_java_pool_zero" = true

FONTE:
How To Determine Granule Size (Doc ID 947152.1)
Java Pool size is larger than specified by parameter java_pool_size. (Doc ID 2036710.1)


Comentários