Ora 29532 ошибка

As I know, Oracle can’t catch the Java errors directly. And the Oracle docs note of the ORA-29532 validate this idea:

ORA-29532: Java call terminated by uncaught Java exception: string

Cause: A Java exception or error was signaled and could not be resolved by the Java code.

Action: Modify Java code, if this behavior is not intended.

According to this text, I think you should handle the exception in the Java code.

You can solve that with these things:

  1. The return value of the Java function may be String — not void, and you may send the error description in the return variable.
  2. You may save the error to an Oracle table in the Java code and read it in the PL/SQL code.
  3. You just send the error to the Oracle user dump file with the System.out.println();.

Edit: Adam’s final solution

This is roughly what I implemented based on the answer:

package mypackage;

public class MyClass {

    public static final int SUCCESS = 1;
    public static final int FAILURE = 0;

    /**
     * This method actually performs the business logic.
     */
    public static void doSomething(String arg1, String arg2) throws SQLException {
        // Actually do something...
    }

    /**
     * This method is called from PL/SQL.
     */
    public static int doSomething(String arg1, String arg2, int[] errorCode, String[] errorMessage) {
        try {
            doSomething(arg1, arg2);
            return success();
        } catch (SQLException e) {
            return failure(e, errorCode, errorMessage);
        }
    }

    private static int success() {
        return SUCCESS;
    }

    private static int failure(SQLException e, int[] errorCode, String[] errorMessage) {
        errorCode[0] = e.getErrorCode();
        errorMessage[0] = e.getMessage();
        return FAILURE;
    }

}

Then in PL/SQL:

SUCCESS CONSTANT BINARY_INTEGER := 1;
FAILURE CONSTANT BINARY_INTEGER := 0;

SUBTYPE error_code_type  IS BINARY_INTEGER;
SUBTYPE error_message_type IS VARCHAR2(1000);

PROCEDURE
  raise_error_if_failure
  (
    status        BINARY_INTEGER,
    error_code    ERROR_CODE_TYPE,
    error_message ERROR_MESSAGE_TYPE
  )
  IS
BEGIN
  IF status = FAILURE THEN
    raise_application_error(error_code, error_message);
  END IF;
END;


FUNCTION
  do_something_in_java
  (
    arg1          VARCHAR2,
    arg2          VARCHAR2,
    error_code    OUT ERROR_CODE_TYPE,
    error_message OUT ERROR_MESSAGE_TYPE
  )
  RETURN BINARY_INTEGER
    AS LANGUAGE JAVA
    NAME 'mypackage.MyClass.doSomething(java.lang.String, java.lang.String, int[], java.lang.String[]) return int';


PROCEDURE
  do_something
  (
    arg1 VARCHAR2,
    arg2 VARCHAR2
  )
IS
  error_code    ERROR_CODE_TYPE;
  error_message ERROR_MESSAGE_TYPE;
BEGIN
  raise_error_if_failure(
      do_something_in_java(arg1, arg2, error_code, error_message),
      error_code,
      error_message
    );
END;

May 2, 2021

I got ” ORA-29532: java call terminated by uncaught java exception: string ” error in Oracle database.

ORA-29532: java call terminated by uncaught java exception: string

Details of error are as follows.

ORA-29532: Java call terminated by uncaught Java exception: string

Cause: A Java exception or error was signaled and could not be resolved by the Java code.

Action: Modify Java code, if this behavior is not intended.

Java permission from 'ORDSYS' is missing and JAVA_ADMIN is missing from SYS
 
call dbms_java.grant_permission ('ORDSYS', 'SYS:java.util.logging.LoggingPermission','control','');
  *
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception:
java.lang.SecurityException: policy table update
SYS:java.util.logging.LoggingPermission, control


java call terminated by uncaught java exception: string

This ORA-29532 errors are related with the Java exception or error was signaled and could not be resolved by the Java code. No system privileges granted or incorrect system privileges granted.

To solve this error, Modify Java code, if this behavior is not intended.

Make sure to grant the right privileges to the user executing the Java Stored Procedures. In the documentation below you can find which privileges needs to be granted for what kind of action.

Or second case’s solution is as follows.

Grant JAVA_ADMIN to SYS then execute the grant_permission step

Grant JAVA_ADMIN to SYS;

conn / as sysdba

call dbms_java.grant_permission ('ORDSYS', 'SYS:java.util.logging.LoggingPermission','control','');

--Reload the Multimedia or reinstall multimedia

connect / as sysdba
drop user ORDDATA cascade;
@?/ord/admin/ordisysc.sql sysaux sysaux -- recreate ORDDATA (ignore user name already exists errors)
@?/ord/im/admin/imprv.sql -- grant privs to ORDDATA

alter session set current_schema=ORDSYS;
@?/ord/im/admin/ordcrtbl.plb -- recreate and load ORDDATA tables
@?/ord/im/admin/imview.sql
@?/ord/im/admin/impbs.sql
@?/ord/im/admin/impvs.sql
@?/ord/im/admin/imtyb.sql
@?/ord/im/admin/implb.sql
@?/ord/im/admin/imxrepos.sql

connect / as sysdba
set serveroutput on;
execute validate_ordim;

select version, status from dba_registry where comp_id='ORDIM';


Do you want to learn Oracle Database for Beginners, then read the following articles.

Oracle Tutorial | Oracle Database Tutorials for Beginners ( Junior Oracle DBA )

Regarding ORA-29532, Oracle support suggested some guide lines to fix the issue. These suggestions outline these error possibilities and resolutions by showing three examples. 

Perhaps one of these examples is similar to your problem with ORA-29532:

The Error:

Sometimes an application running in the Oracle JVM will fail with a java permissions error having the following format when application user tested one Pl/SQL block:

SQL> SET SERVEROUTPUT ON;
SQL> 
DECLARE
V_INFO VARCHAR2(4000):=NULL;
BEGIN
V_INFO:=PKG_VALIDATE.SHOW_STATUS(‘C_CUSTOMER’,’null’);
DBMS_OUTPUT.PUT_LINE (‘V_INFO value is ‘||V_INFO);
DBMS_OUTPUT.PUT_LINE (‘Completed successfully…’);
EXCEPTION WHEN OTHERS THEN  
DBMS_OUTPUT.PUT_LINE (‘ERROR!!!’||SQLERRM);
END;
/
SQL>


anonymous block completed
ERROR ORA-29532: Java call terminated by uncaught Java exception: java.security.AccessControlException: the Permission (java.net.SocketPermission hostname:7001 


connect,resolve) has not been granted to CRM_CUSTOMER. The PL/SQL to grant this is dbms_java.grant_permission( ‘CRM_CUSTOMER’, ‘SYS:java.net.SocketPermission’, ‘hostname:7001’, 


‘connect,resolve’ )

Solution:

exec dbms_java.grant_permission(‘CRM_CUSTOMER’,’SYS:java.io.FilePermission’, ‘/opt/crm/StoredProcLog.log’, ‘write’);
EXEC DBMS_JAVA.GRANT_PERMISSION(‘CRM_CUSTOMER’,’SYS:java.net.SocketPermission’, ‘hostname:7001’, ‘connect,resolve’ );
exec dbms_java.grant_permission(‘CRM_CUSTOMER’,’SYS:java.net.SocketPermission’, ‘hostname:7001’, ‘connect,resolve’ );
exec dbms_java.grant_permission(‘CRM_CUSTOMER’,’SYS:javax.net.ssl.SSLPermission’, ‘setHostnameVerifier’, »);
EXEC DBMS_JAVA.GRANT_PERMISSION(‘CRM_CUSTOMER’,’SYS:java.lang.RuntimePermission’, ‘setFactory’, » );
commit;



Note: Commit is mandatory !!

Java provides 4 Primitive Data Types (byte, short, int, long) to represent integer numbers.
In this Blog, we will look their array size limits in relation to two OracleJVM errors:
ORA-29532 OutOfMemoryError and ORA-27102: out of memory.

Note: Tested in Oracle 19c on Linux.

1. ORA-29532 java.lang.OutOfMemoryError

Nenad’s Blog:
Troubleshooting java.lang.OutOfMemoryError in the Oracle Database
made a deep investigation of ORA-29532 OutOfMemoryError,
and found the internal hard-coded maximum total size in bytes: 536870895
It shows that for int[] array size of 134217723 (0x7FFFFFB, about 128MB Java int), there is no memory error.
However, adding just one additional element will cause OutOfMemoryError
(By default, Java int data type is a 32-bit signed).

We will explore further ORA-29532 OutOfMemoryError
and list the 4 hard-coded integer array size limits on 4 respective Java integer Primitive Data Types.

At first, we copy Nenad’s test code and add one method for byte[].


drop java source "Demo";

create or replace and compile java source named "Demo" as
public class Demo {
    public static void defineIntArray(int p_size) throws Exception {
      //Test of ORA-29532: Java call terminated by uncaught Java exception: java.lang.OutOfMemoryError
      //copy from https://nenadnoveljic.com/blog/troubleshooting-java-lang-outofmemoryerror-in-the-oracle-database/
      int[] v = new int[p_size];
      System.out.println("OracleJvm int[].length: " + v.length);
    }

    public static void defineByteArray(int p_size) throws Exception {
      byte[] v = new byte[p_size];
      System.out.println("OracleJvm byte[].length: " + v.length);
    }
}     
/

create Or replace procedure p_define_int_array (p_size number)
as language java name 'Demo.defineIntArray(int)' ;
/

create Or replace procedure p_define_byte_array (p_size number)
as language java name 'Demo.defineByteArray(int)' ;
/

Run the same test to demonstrate OracleJVM java.lang.OutOfMemoryError exactly at 134217724:


SQL > exec p_define_int_array(134217723);

  OracleJvm int[].length: 134217723


SQL > exec p_define_int_array(134217724);

  Exception in thread "Root Thread" java.lang.OutOfMemoryError
          at Demo.defineIntArray(Demo:29)
  BEGIN p_define_int_array(134217724); END;
  
  *
  ERROR at line 1:
  ORA-29532: Java call terminated by uncaught Java exception: java.lang.OutOfMemoryError
  ORA-06512: at "K.P_DEFINE_INT_ARRAY", line 1
  ORA-06512: at line 1

Following Blog’s guidelines: switch off JIT compiler to obtain descriptive call stack,
we disable OracleJVM Just-in-Time (JIT):


  alter system set java_jit_enabled=false;

and (gdb) disassemble joe_make_primitive_array:


# --------------------------- long, max: 0x3fffffd ---------------------------
  <+107>:   cmp    %r13d,%eax
  <+110>:   jl     0x583c639 <joe_make_primitive_array+121>
  <+112>:   cmp    $0x3fffffd,%rdx
  <+119>:   jbe    0x583c64b <joe_make_primitive_array+139>
  <+121>:   lea    0x11b9ed78(%rip),%rax        # 0x173db3b8 <ioa_ko_j_l_out_of_memory_error>
  <+128>:   mov    %r15,%rdi
  <+131>:   mov    (%rax),%rsi
  <+134>:   callq  0x58459f0 <joe_blow>
  <+139>:   mov    0x1f1(%r15),%r9
# --------------------------- int, max: 0x7fffffb ---------------------------    
  <+299>:   cmp    %r13d,%eax
  <+302>:   jl     0x583c6f9 <joe_make_primitive_array+313>
  <+304>:   cmp    $0x7fffffb,%rdx
  <+311>:   jbe    0x583c70b <joe_make_primitive_array+331>
  <+313>:   lea    0x11b9ecb8(%rip),%rax        # 0x173db3b8 <ioa_ko_j_l_out_of_memory_error>
  <+320>:   mov    %r15,%rdi
  <+323>:   mov    (%rax),%rsi
  <+326>:   callq  0x58459f0 <joe_blow>
  <+331>:   mov    0x1f1(%r15),%r9
# --------------------------- short, max: 0xffffff7 ---------------------------  
  <+491>:   cmp    %r13d,%eax
  <+494>:   jl     0x583c7b9 <joe_make_primitive_array+505>
  <+496>:   cmp    $0xffffff7,%rdx
  <+503>:   jbe    0x583c7cb <joe_make_primitive_array+523>
  <+505>:   lea    0x11b9ebf8(%rip),%rax        # 0x173db3b8 <ioa_ko_j_l_out_of_memory_error>
  <+512>:   mov    %r15,%rdi
  <+515>:   mov    (%rax),%rsi
  <+518>:   callq  0x58459f0 <joe_blow>
  <+523>:   mov    0x1f1(%r15),%r9
# --------------------------- byte, max: 0x1fffffef ---------------------------  
  <+676>:   cmp    %r13d,%eax
  <+679>:   jl     0x583c872 <joe_make_primitive_array+690>
  <+681>:   cmp    $0x1fffffef,%rdx
  <+688>:   jbe    0x583c884 <joe_make_primitive_array+708>
  <+690>:   lea    0x11b9eb3f(%rip),%rax        # 0x173db3b8 <ioa_ko_j_l_out_of_memory_error>
  <+697>:   mov    %r15,%rdi
  <+700>:   mov    (%rax),%rsi
  <+703>:   callq  0x58459f0 <joe_blow>
  <+708>:   mov    0x1f1(%r15),%r9

Copy 4 hex constants from above 4 cmp instructions and map to 4 integer Primitive Data Types:


  long  (8 bytes, 0x3fffffd =67108861 )
  int   (4 bytes, 0x7fffffb =134217723) 
  short (2 bytes, 0xffffff7 =268435447)
  byte  (1 byte,  0x1fffffef=536870895)

Above assemble code shows that each integer type is handled individually with different hard-coded limit,
but total memory is capped below 512MB.

For example, for data type int, the input parameter array size
(register rdx, passed as arg2 to joe_make_primitive_array)
is checked against fixed constant 0x7fffffb (134217723, a hard-coded value).
According to cmp status flags, create array if rdx below or equal to 0x7fffffb
(%rdx — $0x7fffffb, CF=1 or ZF=1);
otherwise continue to «ioa_ko_j_l_out_of_memory_error».


  <+304>:   cmp    $0x7fffffb,%rdx
  <+311>:   jbe    0x583c70b <joe_make_primitive_array+331>
  <+313>:   lea    0x11b9ecb8(%rip),%rax        # 0x173db3b8 <ioa_ko_j_l_out_of_memory_error>

We can also see that there is another memory pre-check before each integer type check.
If the memory limit in eax is less than input parameter array size in r13d (%r13d > %eax),
then jump to «ioa_ko_j_l_out_of_memory_error»
(Note: maximum rax seems 0x20000000=536870912=512MB,
probably default Heap Size since 11.2, see later appended MOS Doc ID 2526642.1).


  <+299>:   cmp    %r13d,%eax
  <+302>:   jl     0x583c6f9 <joe_make_primitive_array+313>

Now we can verify the limit of byte integer type exactly at 536870896:


SQL > exec p_define_byte_array(536870895);
  OracleJvm byte[].length: 536870895

SQL > exec p_define_byte_array(536870896);
  Exception in thread "Root Thread" java.lang.OutOfMemoryError
          at Demo.defineByteArray(Demo:31)
  BEGIN p_define_byte_array(536870896); END;
  
  *
  ERROR at line 1:
  ORA-29532: Java call terminated by uncaught Java exception: java.lang.OutOfMemoryError
  ORA-06512: at "K.P_DEFINE_BYTE_ARRAY", line 1
  ORA-06512: at line 1

Oracle MOS: Java Stored Procedure suddenly fails with java.lang.OutOfMemoryError (Doc ID 2526642.1) wrote:

Symptoms
  A database routine implemented as a Java Stored procedure receives the following error.
  ORA-29532: Java call terminated by uncaught Java exception: java.lang.OutOfMemoryError
  This routine may have worked previously or it may be brand new development.
  
Cause
  The DB JVM does not have enough session Heap Memory. This error occurs when a Java Stored Procedure 
  (ie. a PL/SQL routine where the body is implemented in Java ) does not have enough Heap space 
  to work with the amount of data being processed. If this were a client-side java program 
  using the Java Runtime Engine (JRE) (ie. java.exe), one would use the -Xmx parameter to configure the Heap Memory.  
  However, as the Oracle DB JVM is running in the process space of the Oracle executable, 
  there is no way to use the -Xmx switch.  The JVM has a default Heap Size (512MB since 11.2) 
  but it is also configurable using a method in the "Java Runtime" class called "oracle.aurora.vm.OracleRuntime".  
  Along with other "java runtime" related switches, this class contains a couple methods 
  that can be used to manage the Java Heap Size.  Therefore, if you encounter the OutOfMemoryError 
  and need to increase from either the default or a previous configured amount, 
  you can use oracle.aurora.vm.OracleRuntime.setMaxMemorySize to allocate more memory for the Java Heap.

The MOS Note described that
«Oracle DB JVM is running in the process space of the Oracle executable»
and had one hint about 512MB: «The JVM has a default Heap Size (512MB since 11.2)».
As one Solution, MOS Note provided following workaround.


create or replace package Java_Runtime is
  function getHeapSize return number;
  function setHeapSize(num number) return number;
end Java_Runtime;
/

create or replace package body Java_Runtime is
  function getHeapSize return number is
    language java name 'oracle.aurora.vm.OracleRuntime.getMaxMemorySize() returns long';
  function setHeapSize(num number) return number is
    language java name 'oracle.aurora.vm.OracleRuntime.setMaxMemorySize(long) returns long';
end Java_Runtime;
/

declare
   heap_return_val NUMBER;
begin
   -- MOS code has a typo, setMaxMemorySize should be setHeapSize
   -- heap_return_val := Java_Runtime.setMaxMemorySize(1024*1024*1024);
   
   dbms_output.put_line('HeapSize Before Set: '||Java_Runtime.getHeapSize);
   heap_return_val := Java_Runtime.setHeapSize(1024*1024*1024);
   dbms_output.put_line('HeapSize After Set: '||Java_Runtime.getHeapSize);
   
   -- MOS code
   -- MY_JAVA_STORED_PROC(...);
   
   p_define_int_array(134217724);
end;
/

HeapSize Before Set: 536870912
HeapSize After Set: 1073741824
declare
*
ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception: java.lang.OutOfMemoryError
ORA-06512: at "K.P_DEFINE_INT_ARRAY", line 1
ORA-06512: at line 14

We made the test in Oracle 12c and 19c and still got ORA-29532 OutOfMemoryError
(for the reason of the hard-coded limit discovered by Nenad’s Blog).

2. ORA-27102: out of memory

Blog:
Oracle JVM Java OutOfMemoryError and lazy GC
was trying to bring up some discussions on OracleJVM OutOfMemoryError
in connection with lazy GC.

The first test in the Blog is to allocate 511MB byte array:


SQL > exec createBuffer512(1024*1024*511);
  PL/SQL procedure successfully completed

succeeded without Error.

but the second test with 512MB:


SQL > exec createBuffer512(1024*1024*512);
  
  ERROR at line 1:
  ORA-29532: Java call terminated by uncaught Java exception: java.lang.OutOfMemoryError
  ORA-06512: at "K.CREATEBUFFER512", line 1
  ORA-06512: at line 1

hit the general Java error: ORA-29532 java.lang.OutOfMemoryError, which probably indicates
that the JVM is limited by 512MB for one single object instance, in this test, it is «new byte[bufferSize]».

We can see that above hard-coded byte[] limit of 536870895 (0x1fffffef) is between 511MB and 512MB.


   1024*1024*512=536870912 > 536870895 > 535822336=1024*1024*511.

Run a third test case, which gradually allocates memory from 1MB to 511MB, each time increases 1MB per call.


SQL > exec createBuffer512_loop(511, 1, 1);

  Step -- 1 --, Buffer Size (MB) = 1
  Step -- 2 --, Buffer Size (MB) = 2
  Step -- 3 --, Buffer Size (MB) = 3
  ...
  Step -- 202 --, Buffer Size (MB) = 202
  Step -- 203 --, Buffer Size (MB) = 203

  ERROR at line 1:
  ORA-27102: out of memory
  Linux-x86_64 Error: 12: Cannot allocate memory
  Additional information: 12394
  Additional information: 218103808
  ORA-06512: at "K.CREATEBUFFER512", line 1
  ORA-06512: at "K.CREATEBUFFER512_LOOP", line 8
  ORA-06512: at line 1

It reveals that out of memory can be generated even under above discussed hard-coded limit (203MB < 512MB),
but the error code is ORA-27102 (in 12c, we saw ORA-29532).
The test shows that above 4 integer array size limits for respective 4 integer Primitive Data Types
are sufficient, but not necessary conditions for out of memory.

Make a 27102 trace:


  alter session set max_dump_file_size = unlimited;
  alter session set tracefile_identifier='ORA27102_trc3'; 
  alter session set events '27102 trace name errorstack level 3'; 
  exec createBuffer512_loop(511, 1, 1);

Here the extracted error message, call stack, and session wait event from trace file:


----- Error Stack Dump -----
Linux-x86_64 Error: 12: Cannot allocate memory
Additional information: 12394
Additional information: 218103808

BEGIN createBuffer512_loop(511, 1, 1); END;
----- PL/SQL Call Stack -----
  object      line  object
  handle    number  name
0x91948d30         1  procedure K.CREATEBUFFER512
0x8ef98db0         8  procedure K.CREATEBUFFER512_LOOP
0x8ca47e38         1  anonymous block

----- Call Stack Trace -----
FRAME [12] (dbgePostErrorKGE()+1066 -> dbkdChkEventRdbmsErr())
FRAME [13] (dbkePostKGE_kgsf()+71 -> dbgePostErrorKGE())
FRAME [14] (kgerscl()+546 -> dbkePostKGE_kgsf())
FRAME [15] (kgecss()+69 -> kgerscl())
FRAME [16] (ksmrf_init_alloc()+821 -> kgecss())
  CALL TYPE: call   ERROR SIGNALED: yes   COMPONENT: KSM
FRAME [17] (ksmapg()+521 -> ksmrf_init_alloc())
FRAME [18] (kgh_invoke_alloc_cb()+162 -> ksmapg())
  RDI 000000000D000000 RSI 00007F4D777511E0 RDX 000000000CE2D8B0 
FRAME [19] (kghgex()+2713 -> kgh_invoke_alloc_cb())
FRAME [20] (kghfnd()+376 -> kghgex())
FRAME [21] (kghalo()+4908 -> kghfnd())
FRAME [22] (kghgex()+593 -> kghalo())
FRAME [23] (kghfnd()+376 -> kghgex())
FRAME [24] (kghalo()+4908 -> kghfnd())
FRAME [25] (kghgex()+593 -> kghalo())
FRAME [26] (kghalf()+617 -> kghgex())
FRAME [27] (ioc_allocate0()+1094 -> kghalf())
FRAME [28] (iocbf_allocate0()+53 -> ioc_allocate0())
FRAME [29] (ioc_do_call()+1297 -> iocbf_allocate0())
FRAME [30] (joet_switched_env_callback()+376 -> ioc_do_call())
FRAME [31] (ioct_allocate0()+79 -> joet_switched_env_callback())
FRAME [32] (eoa_new_mman_segment()+368 -> ioct_allocate0())
FRAME [33] (eoa_new_mswmem_chunk()+66 -> eoa_new_mman_segment())
FRAME [34] (eomsw_allocate_block()+229 -> eoa_new_mswmem_chunk())
FRAME [35] (eoa_alloc_mswmem_object_no_gc()+2037 -> eomsw_allocate_block())
FRAME [36] (eoa_alloc_mswmem_object()+48 -> eoa_alloc_mswmem_object_no_gc())
FRAME [37] (eoa_new_ool_alloc()+508 -> eoa_alloc_mswmem_object())
FRAME [38] (joe_make_primitive_array()+828 -> eoa_new_ool_alloc())
FRAME [39] (joe_run_vm()+15736 -> joe_make_primitive_array())
FRAME [40] (joe_run()+608 -> joe_run_vm())
FRAME [41] (joe_invoke()+1156 -> joe_run())
FRAME [42] (joet_aux_thread_main()+1674 -> joe_invoke())
FRAME [43] (seoa_note_stack_outside()+34 -> joet_aux_thread_main())
FRAME [44] (joet_thread_main()+64 -> seoa_note_stack_outside())
FRAME [45] (sjontlo_initialize()+178 -> joet_thread_main())
FRAME [46] (joe_enter_vm()+1197 -> sjontlo_initialize())
FRAME [47] (ioei_call_java()+4716 -> joe_enter_vm())
FRAME [48] (ioesub_CALL_JAVA()+569 -> ioei_call_java())
FRAME [49] (seoa_note_stack_outside()+34 -> ioesub_CALL_JAVA())
FRAME [50] (ioe_call_java()+292 -> seoa_note_stack_outside())
FRAME [51] (jox_invoke_java_()+4133 -> ioe_call_java())
FRAME [52] (kkxmjexe()+1493 -> jox_invoke_java_())

    Session Wait History:
     0: waited for 'PGA memory operation'
        =0xd000000, =0x2, =0x0

«Error: 12» is ENOMEM defined in /usr/include/asm-generic/errno-base.h.

«Additional information: 12394» is not clear.

«Additional information: 218103808» points out P1 parameter in
Event «PGA memory operation» (12.2 new introduced),
which also appears in «RDI 000000000D000000» of kgh_invoke_alloc_cb call (0xd000000 = 218103808).

In the above call stack, there is a subroutine «FRAME [35] (eoa_alloc_mswmem_object_no_gc()», with suffix «no_gc».

«FRAME [38] (joe_make_primitive_array()+828 -> eoa_new_ool_alloc())» shows that «joe_make_primitive_array»
already passed line <+708> of byte array size check (see above disassembled code), and is calling «eoa_new_ool_alloc».

Occasionally, session is terminated:


SQL > exec createBuffer512_loop(511, 1, 1);
  ERROR:
  ORA-03114: not connected to ORACLE
  ORA-03113: end-of-file on communication channel
  Process ID: 14461
  Session ID: 907 Serial number: 50430

and Linux dmesg shows:


  Out of memory: Kill process 14461 (oracle_14461_c0) score 781 or sacrifice child
  Killed process 14461 (oracle_14461_c0) total-vm:23745148kB, anon-rss:18595960kB, file-rss:132kB, shmem-rss:538232kB

3. Out of Memory Error Application Handling

If PL/SQL applications hit out of Memory Error even under the discussed hard-coded limit,
one possible workaround is try to catch the error, invoke dbms_java.endsession
to release memory, and then re-try the application as follows:


set serveroutput on size 50000;
exec dbms_java.set_output(50000);

declare
  java_oom_29532    exception;
  pragma            exception_init(java_oom_29532, -29532);
  l_es_ret          varchar2(100);
begin
  p_define_int_array(134217724);   -- only illustrative demo, real application should use size below the limit
  exception 
    when java_oom_29532 then
      dbms_output.put_line('------ int[134217724] hit ORA-29532: java.lang.OutOfMemoryError ------');
      l_es_ret  := dbms_java.endsession;
      p_define_int_array(134217723);
      dbms_output.put_line('------ int[134217723] Succeed ------');
    when others then
      raise;
end;
/

Exception in thread "Root Thread" java.lang.OutOfMemoryError
        at Demo.defineIntArray(Demo:5)
------ int[134217724] hit ORA-29532: java.lang.OutOfMemoryError ------
OracleJvm int[].length: 134217723
------ int[134217723] Succeed ------

set serveroutput on size 50000;
exec dbms_java.set_output(50000);

declare
  java_oom_27102    exception;
  pragma            exception_init(java_oom_27102, -27102);
  l_es_ret          varchar2(100);
begin
  createBuffer512_loop(511, 1, 1); 
  exception 
    when java_oom_27102 then
      dbms_output.put_line('------ createBuffer512_loop hit ORA-27102: out of memory ------');
      l_es_ret  := dbms_java.endsession;
      createBuffer512_loop(3, 1, 1);
      dbms_output.put_line('------ createBuffer512_loop(3, 1, 1) Succeed ------');
    when others then
      raise;
end;
/

Step -- 284 --, Buffer Size (MB) = 284
Step -- 285 --, Buffer Size (MB) = 285
------ createBuffer512_loop hit ORA-27102: out of memory ------
Step -- 1 --, Buffer Size (MB) = 1
Step -- 2 --, Buffer Size (MB) = 2
Step -- 3 --, Buffer Size (MB) = 3
------ createBuffer512_loop(3, 1, 1) Succeed ------   

Oracle database Jave stored procedure failed with «java.lang.OutOfMemoryError», the error stack looks like

ORA-29532: Java call terminated by uncaught Java exception: java.lang.OutOfMemoryError

ORA-06512: at «USER01.MYJAVAPROC», line 28

ORA-06512: at line 7

This error is thrown when there is insufficient space to allocate an object in the Java heap. In this case, The Java garbage collector cannot make space available to accommodate a new object, and the heap cannot be expanded further.  

As we know, Java stored procedure is impleted in Java, so that the excution of the procedure also follows the same rule as normal Java application doing. The only difference is that the procedure is running on JVM built inside database, not normal Java Runtime Engine (java.exe).

When normal Java application got out of memory error, parameter -Xmx can be used while starting the application to configure the heap memory with larger value. However, as the Oracle Databae JVM is running in the process space of the Oracle executable, there is no way to use the -Xmx parameter.  But it is also configurable using a method in the «Java Runtime» class «oracle.aurora.vm.OracleRuntime». The class has following methods,

    getMaxMemorySize   — Get current setting of heap size

    setMaxMemorySize   — Set new heap size

In order to call the methods inside database, we have to create Java stored procedure to expose the method to Oracle database, the example code as following

create or replace function get_java_heap_size return number is

    language java name ‘oracle.aurora.vm.OracleRuntime.getMaxMemorySize() returns long’;

create or replace function set_java_heap_size(mem_size number) return number is

    language java name ‘oracle.aurora.vm.OracleRuntime.setMaxMemorySize(long) returns long’;

The out of memory error can be fixed by running created Jave store procedure set_java_heap_size before running the application Java stored procedure which triggers the error. For example

declare

  heap_size number;

begin

  — Set heap size to 1GB

  heap_size := set_java_heap_size(1024*1024*1024);

  — Run application Java stored procedure

  user01.myjavaproc;

end;

/

Понравилась статья? Поделить с друзьями:
  • Ora 28860 неустранимая ошибка ssl
  • Opera twitch ошибка 4000
  • Ora 28040 no matching authentication protocol ошибка
  • Opera installer ошибка
  • Ora 27477 ошибка