除了使用ALTER SESSION设置会话的状态,利用V$SESSION查询会话状态,Oracle还提供了PL/SQL接口DBMS_SESSION来查询和设置会话相关的状态。
描述释放用户内存的FREE_UNUSED_USER_MEMORY过程。
DBMS_SESSION包小议(一):http://yangtingkun.itpub.net/post/468/498365
DBMS_SESSION包小议(二):http://yangtingkun.itpub.net/post/468/498408
DBMS_SESSION包小议(三):http://yangtingkun.itpub.net/post/468/498451
DBMS_SESSION包小议(四):http://yangtingkun.itpub.net/post/468/498475
DBMS_SESSION包小议(五):http://yangtingkun.itpub.net/post/468/498559
一般来说设置会话级的状态都是通过ALTER SESSION语句,也有个别的例外,比如角色的设置是通过SET语句实现的。Oracle除了提供SQL的方法外,还提供了PL/SQL的接口,DBMS_SESSION包,将会话状态的设置和查询集成在这个包中。
通过一个例子来说明这个过程的功能:
SQL> CREATE TABLE T_LOB
2 (ID NUMBER,
3 CONTENTS CLOB);
表已创建。
SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_STR VARCHAR2(32767) := LPAD('A', 32767, 'A');
3 V_LOB CLOB;
4 V_PGA NUMBER;
5 BEGIN
6 SELECT VALUE
7 INTO V_PGA
8 FROM V$MYSTAT A, V$STATNAME B
9 WHERE A.STATISTIC# = B.STATISTIC#
10 AND NAME = 'session pga memory';
11
12 DBMS_OUTPUT.PUT_LINE('BEFORE INSERT:' || V_PGA);
13
14 INSERT INTO T_LOB
15 VALUES (1, EMPTY_CLOB())
16 RETURN CONTENTS
17 INTO V_LOB;
18
19 FOR I IN 1..100 LOOP
20 DBMS_LOB.WRITEAPPEND(V_LOB, LENGTH(V_STR), V_STR);
21 END LOOP;
22
23 COMMIT;
24
25 SELECT VALUE
26 INTO V_PGA
27 FROM V$MYSTAT A, V$STATNAME B
28 WHERE A.STATISTIC# = B.STATISTIC#
29 AND NAME = 'session pga memory';
30
31 DBMS_OUTPUT.PUT_LINE('AFTER INSERT:' || V_PGA);
32
33 SELECT CONTENTS
34 INTO V_LOB
35 FROM T_LOB
36 WHERE ID = 1;
37
38 SELECT VALUE
39 INTO V_PGA
40 FROM V$MYSTAT A, V$STATNAME B
41 WHERE A.STATISTIC# = B.STATISTIC#
42 AND NAME = 'session pga memory';
43
44 DBMS_OUTPUT.PUT_LINE('AFTER SELECT:' || V_PGA);
45
46 DBMS_SESSION.FREE_UNUSED_USER_MEMORY;
47
48 SELECT VALUE
49 INTO V_PGA
50 FROM V$MYSTAT A, V$STATNAME B
51 WHERE A.STATISTIC# = B.STATISTIC#
52 AND NAME = 'session pga memory';
53
54 DBMS_OUTPUT.PUT_LINE('AFTER FREE:' || V_PGA);
55 END;
56 /
BEFORE INSERT:2965384
AFTER INSERT:10370952
AFTER SELECT:10370952
AFTER FREE:3161992
PL/SQL 过程已成功完成。
利用这个过程,可以PL/SQL过程中释放已经不在需要使用的内存。在正常情况下,用户分配的内存被使用完成后,并不会立即释放给Oracle,而是预备给同样的操作后续使用,比如分配给排序的内存预备为后续的排序使用。
在这个例子中,使用了10M的PGA用于存放LOB信息,而在执行了FREE_UNUSED_USER_MEMORY过程后,这些内存被释放,只保留了3M左右的基本内存。
SQL> DECLARE
2 V_STR VARCHAR2(32767) := LPAD('A', 32767, 'A');
3 V_LOB CLOB;
4 V_PGA NUMBER;
5 BEGIN
6 SELECT VALUE
7 INTO V_PGA
8 FROM V$MYSTAT A, V$STATNAME B
9 WHERE A.STATISTIC# = B.STATISTIC#
10 AND NAME = 'session pga memory';
11
12 DBMS_OUTPUT.PUT_LINE('BEFORE INSERT:' || V_PGA);
13
14 INSERT INTO T_LOB
15 VALUES (2, EMPTY_CLOB())
16 RETURN CONTENTS
17 INTO V_LOB;
18
19 FOR I IN 1..100 LOOP
20 DBMS_LOB.WRITEAPPEND(V_LOB, LENGTH(V_STR), V_STR);
21 END LOOP;
22
23 COMMIT;
24
25 SELECT VALUE
26 INTO V_PGA
27 FROM V$MYSTAT A, V$STATNAME B
28 WHERE A.STATISTIC# = B.STATISTIC#
29 AND NAME = 'session pga memory';
30
31 DBMS_OUTPUT.PUT_LINE('AFTER INSERT:' || V_PGA);
32 END;
33 /
BEFORE INSERT:3096456
AFTER INSERT:10370952
PL/SQL 过程已成功完成。
SQL> SELECT VALUE
2 FROM V$MYSTAT A, V$STATNAME B
3 WHERE A.STATISTIC# = B.STATISTIC#
4 AND NAME = 'session pga memory';
VALUE
----------
2834312
即使不调用FREE_UNUSED_USER_MEMORY过程,在PL/SQL执行完成后,内存也会自动被释放,而FREE_UNUSED_USER_MEMORY过程唯一的功能,就是在PL/SQL执行过程中释放掉不再需要的用户内存。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-630550/ ,如需转载,请注明出处,否则将追究法律责任。