Links
Home
Oracle DBA Forum
Frequent Oracle Errors
TNS:could not resolve the connect identifier specified
Backtrace message unwound by exceptions
invalid identifier
PL/SQL compilation error
internal error
missing expression
table or view does not exist
end-of-file on communication channel
TNS:listener unknown in connect descriptor
insufficient privileges
PL/SQL: numeric or value error string
TNS:protocol adapter error
ORACLE not available
target host or object does not exist
invalid number
unable to allocate string bytes of shared memory
resource busy and acquire with NOWAIT specified
error occurred at recursive SQL level string
ORACLE initialization or shutdown in progress
archiver error. Connect internal only, until freed
snapshot too old
unable to extend temp segment by string in tablespace
Credential retrieval failed
missing or invalid option
invalid username/password; logon denied
unable to create INITIAL extent for segment
out of process memory when trying to allocate string bytes
shared memory realm does not exist
cannot insert NULL
TNS:unable to connect to destination
remote database not found'>ora-02019
exception encountered: core dump
inconsistent datatypes
no data found
TNS:operation timed out
PL/SQL: could not find program
existing state of packages has been discarded
maximum number of processes exceeded
error signaled in parallel query server
ORACLE instance terminated. Disconnection forced
TNS:packet writer failure
see ORA-12699
missing right parenthesis
name is already used by an existing object
cannot identify/lock data file
invalid file operation
quoted string not properly terminated
How to locate packages that do not deallocate PL/SQL collections

How to locate packages that do not deallocate PL/SQL collections

2005-05-13       - By Buechi Martin

Reply:     1     2     3  

All,

I found the answer to my question myself. I am sharing it because it
might be of general interest. Enjoy!

The basic idea is that by recompiling a package body, the associated
session memory of global variables gets freed, but no other memory.

The script below works provided that package headers don't cause the
memory leak, it is possible to recompile the bodies (no other sessions
locking them), and the script is run in the session that holds on to the
excessive amount of memory. The first restriction can be overcome if
there are no circular dependencies - but proper information hiding
should not make this necessary in most cases. The second is a conditio
sine qua non. The third can be solved by a small modification of the
script.

Regards,

Martin

--

-- Setup
drop table pkg_mem_alloc;
create table pkg_mem_alloc(
 name                       varchar2(1000)
,pga_alloc_mem              number
,pga_used_mem               number
);
create or replace procedure mem_alloc(
 o_pga_alloc_mem        out number
,o_pga_used_mem         out number
)
as
begin
 dbms_session.free_unused_user_memory;
 select v.pga_alloc_mem
       ,v.pga_used_mem
 into   o_pga_alloc_mem
       ,o_pga_used_mem
 from   gv$session g
       ,v$process  v
 where  sid =3D (select sid from v$mystat where rownum=3D1)
    and g.paddr =3D v.addr;
end mem_alloc;
/

-- Run
-- No other sessions running or compile will hang!
-- No useful results if memory hangs off packages rather than bodies!
set serveroutput on size 100000
truncate table pkg_mem_alloc;
variable l_last_pga_alloc_mem number
variable l_last_pga_used_mem number
declare
 type t_varchar_tab is table of v$access.object%type index by
pls_integer;
 l_pkg_list                 t_varchar_tab;
 l_last_pga_alloc_mem       number;
 l_cur_pga_alloc_mem        number;
 l_last_pga_used_mem        number;
 l_cur_pga_used_mem         number;
 l_pkg_name                 v$access.object%type;
begin
 select distinct(object)
 bulk collect into l_pkg_list
 from   v$access
 where  sid =3D (select sid from v$mystat where rownum=3D1)
    and type like 'PACKAGE%'
    and owner =3D 'K';=20
 mem_alloc(l_last_pga_alloc_mem, l_last_pga_used_mem);
 for i in 1..l_pkg_list.count loop
   l_pkg_name :=3D l_pkg_list(i);
   begin
     execute immediate 'alter package "' || l_pkg_name || '" compile
body';
   exception
     when others then
        dbms_output.put_line('Problem compiling package body ' ||
l_pkg_name);
   end;
   mem_alloc(l_cur_pga_alloc_mem, l_cur_pga_used_mem);
   insert into pkg_mem_alloc values(
     l_pkg_name
    ,l_last_pga_alloc_mem - l_cur_pga_alloc_mem
    ,l_last_pga_used_mem  - l_cur_pga_used_mem
   );
   commit;
   l_last_pga_alloc_mem :=3D l_cur_pga_alloc_mem;
   l_last_pga_used_mem :=3D l_cur_pga_used_mem;=20
 end loop;
 :l_last_pga_alloc_mem :=3D l_last_pga_alloc_mem;
 :l_last_pga_used_mem  :=3D l_last_pga_used_mem; =20
end;
/
exec dbms_session.reset_package
declare
 l_cur_pga_alloc_mem        number;
 l_cur_pga_used_mem         number;
begin
 mem_alloc(l_cur_pga_alloc_mem, l_cur_pga_used_mem);
 insert into pkg_mem_alloc values(
   'Package headers/unknown'
  ,:l_last_pga_alloc_mem - l_cur_pga_alloc_mem
  ,:l_last_pga_used_mem  - l_cur_pga_used_mem
 );
 commit;
end;
/
column name format a30
select name
     ,pga_used_mem / 1024 / 1024  "pga_used_mem MB"
from pkg_mem_alloc
order by 2 desc;

=20
-- --Original Message-- --
From: Buechi Martin=20
Sent: Donnerstag, 12. Mai 2005 17:10
To: oracle-l@(protected)
Subject: How to locate packages that do not deallocate PL/SQL
collections

All,

We have an application with 4,200 PL/SQL packages on Oracle 9.2.0.5 on =
=3D
AIX 5.3. Many of them use associative arrays (index-by tables) and SQL =
=3D
varrays. One or more of these packages does not properly free its memory
=3D
after usage resulting in an ever growing PGA size (up to 1GB followed by
=3D
ERROR: ORA-04030 (See ORA-04030.ora-code.com): out of process memory when trying to allocate 16408 =
=3D
bytes (koh-kghu sessi,pl/sql vc2), ORA-06500 (See ORA-06500.ora-code.com): PL/SQL: storage error, =3D
v$process.pga_freeable_mem below 1 MB).

If I grow a session and then execute =3D
dbms_session.free_unused_user_memory, the PGA size =3D
(v$process.pga_alloc_mem and v$process.pga_used_mem) does not decrease.
=3D
If I execute first dbms_session.reset_package and then =3D
dbms_session.free_unused_user_memory, both values do decrease down to a
=3D
couple of MB.

My assumption is that this is our own programming error (missing =3D
table.delete) rather than a PL/SQL memory leak because it started to =3D
appear when the application was changed (lots of changes, making it hard
=3D
to isolate the faulty change) and not on an Oracle release change.

To locate the source of the problem, we are looking for a way to find =
=3D
out which package holds on to how much heap memory in terms of PL/SQL =
=3D
and SQL collection variables. Is there a way to find this out, e.g., by
=3D
dumping the process memory? (I tried with immediate trace name heapdump
=3D
1 and 4, but could not find the desired information.)

If such a feature is not available in 9.2.0.5, but in 10.1.0.3 or 10gR2
=3D
Beta 3, we could load the application onto one of these releases.

Regards,

Martin

P.S.   Unrelated question: Does Oracle use distinct cache buffer hash =3D
buckets and cache buffer chain latches for tablespace with non-default =
=3D
block sizes? If not, I guess I can find out by creating such a =3D
tablespace and looking at x$bh.

-- ---- ---- ---- ---- ---- ---- ---- ----=3D20
A v a l o q - essential for banking=3D20
Avaloq Evolution AG=3D20
Allmendstrasse 140, 8027 Z=3DFCrich=3D20
T +41 44 488 6888, F +41 44 488 6868, <http://www.avaloq.com/>=3D20
Martin B=3DFCchi <mailto:martin.buechi@(protected)>=3D20

--
http://www.freelists.org/webpage/oracle-l
--
http://www.freelists.org/webpage/oracle-l