Scott,
Thanks for the detailed response. It really helped.
Kurt Anderson
Application Developer
Highsmith
-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Friday, September 19, 2008 3:40 PM
To: RPG programming on the AS400 / iSeries
Subject: Re: Dynamic Array as return/output parameter in export
procedure
Hi Kurt,
Does automatic cleanup ever clear out the value at the address? My
knowledge of the behind the scenes memory management is basic at best.
I think you're asking whether it deallocates the memory at the address,
right? I just want to make I'm clear (not just to you, but to others
who may find this message) We're not talking about zeroing out or
blanking the memory (for the moment anyway). When you say "clear out
the value" you really mean deallocate, right?
Basically there are three types of memory allocations:
a) Static
b) Automatic
c) Heap
Static allocations are what RPG does for global variables, or for
subprocedure variables where the 'static' keyword is coded. Static
variables are allocated when the program is activated. It is
deallocated when the activation group ends (in ILE) or when the program
ends with *INLR on (in OPM or DFTACTGRP(*YES))
Automatic allocations are created when the routine is called. In RPG,
that means, when a subprocedure is invoked, all of it's local variables
(not declared with static or based) are allocated. When the
subprocedure ends, the memory is deallocated. I'm not sure how
automatic allocation works on the i -- but I know that on the PC it
simply reserves space on the stack by incrementing the stack pointers,
and releases the memory by decrementing them. Automatic storage is
therefore VERY FAST to allocate/deallocate, since it involves nothing
more than adding or subtracting from a number. I suspect that the i
does something similar. But, of course, RPG also zeroes/blanks the
variables, and that's where there might be a performance hit.
CL programs use automatic storage even for their global variables in the
main procedure (of course, that's all there is in CL). So CL programs
allocate/deallocate their variables on every call. RPG uses static
variables at the global level, and automatic variables at the procedure
level, which means that global variables remain even after the program
ends. (A tool that has been used to great effect in some RPG shops.)
Heap storage is manually allocated by a programmer, and manually
deallocated by a programmer, as discussed previously.
A pointer is a variable -- never forget that -- it's a variable that
requires 16 bytes of memory, in which it stores a memory address. In
Lim's example, the pointer was in automatic storage. So when the
procedure started up, it grabbed 16 bytes of memory (possibly from the
stack) and set it to hex zeroes (*null). When %ALLOC() ran, it
allocated memory from the heap, and stored the address where that memory
could be found in those 16 bytes of automatic storage.
When the procedure ends, the address is certainly removed from that
automatic storage, and the automatic storage is freed up.
However, the spot on the heap is still allocated to the program. As
long as you saved that address to a different variable (which Lim did,
he copied it to a parameter) there's no danger. The heap memory will
never be deallocated unless you explicitly call the DEALLOC op-code (or
a similar tool, such as ILE C's free() function). The heap memory will
always remain allocated (even if you accidentally lose the address!)
until the activation group ends.
Hopefully that's clear enough (and long winded enough).
There's no situation where the deallocation of a pointer would cause the
memory it refers to to be deallocated.
Some newer languages (such as Java) have features like that, though.
Java doesn't have pointers, so it's not quite the same thing. But, the
JVM keeps track of every reference to a Java object. When all
references are gone, the garbage collector will free up the memory of
that Java object.
RPG is not like that. Even if all pointers that point to a space in
memory are gone, the system will continue to reserve it until the
activation group is reclaimed (or the job ends, which also ends the
actgrp)
Indeed, I've always thought of activation groups as garbage collectors.
If you use ACTGRP(*NEW) to the initial program off of a menu, and then
use *CALLER for all sub-programs/srvpgms, when the user returns to the
memory, it automatically cleans everything up. For a long time I tried
to convince everyone that this was the best way to use activation
groups, because I felt the cleanup process was useful. Eventually,
though, I gave up on that tactic. RPGers always seem to want to have
one value for the actgrp parameter that they can specify everywhere
rather than having to understand actgrps and use the right one for the
situation... so I gave up on trying to convince people to use
*NEW/*CALLER and just tell people to use a named group, now. Sad,
really.
--
This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing
list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe,
unsubscribe, or change list options,
visit:
http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at
http://archive.midrange.com/rpg400-l.
As an Amazon Associate we earn from qualifying purchases.