Operating System - OpenVMS
Showing results for 
Search instead for 
Did you mean: 

P0 space of memory leak


P0 space of memory leak


I have some problem with the P0 space leaking memory.

I am using sys$mgblsc function to map global section and sys$deltva to free up that memory space. Code flow is as follows:



2 [Wait for the request from user]

/* Got the request from user */


/* First time memory will not be mapped so the following statement will not be executed */

4 SYS$DELTVA (pc_gs_bounds, retadr, 0 )

/* Map the memory */

5 sys$mgblsc

status = SYS$MGBLSC ( inadr,
pc_gs_bounds, 0,
gs_ident, 0 ) ;

6 [ Now execute the remaining part of the code ]

7 [ Everthing done, goto RECALL ]


I am running the debug image of the code along with heap analyzer and I am having some confusing results:

Giving request for FIRST Time:

Program counter is at 2 and it is waiting for the request from user, I entered the request it checks the whether the memory is mapped or not ( at 3) since for the first time it is not mapped so 4 will not be executed and it comes directly to 5. After the exectuion of 5 global section section of memory is mapped onto the P0 space of the process.

From Heap Analyzer:

Mapped at following location:
00FB8000+0E2C2000=0F27A000 SYS$MGBLSC - "XXXXXXXX" (P0 Region).

From f$getjpi(pid,"FREP0VA")
Before step 5: 00A8F4DE
After step 5: 0F2E0000

Value of pc_gs_bounds[0:1] from debug image:
[0]: 16482304
[1]: 254255103

After this execution of the program completes and it again goes at 2, waiting for request from user. Everthing works fine till here.

Giving request for SECOND Time:

Now I give the request second time. Since memory is mapped the previous time so it goes at step 4. Return value at 4 is SS$_SUCCESS. But I got some contradictory results from heap analyzer and f$getjpi.

From Heap Analyzer:

Memory is unmaped, but

From f$getjpi(pid,"FREP0VA")

It still gives: 0F2E0000

Values of pc_gs_bounds and retadr at 4 are:

[0]: 16482304
[1]: 254255103
[0]: 16482304
[1]: 254255103

Now it comes at step 5. After execution of step 5, results are as follows:

Form Heap Analyzer:

Memory is again mapped at following location:

0F2E0000+0E2C2000=1D5A2000 SYS$MGBLSC - "XXXXXXXX" (P0 Region).

From f$getjpi(pid,"FREP0VA")

It increases its value and gives: 1D5A2000

Value of pc_gs_bounds[0:1] from debug image:
[0]: 254672896
[1]: 492445695

Can anyone help me to know

1) Where P0 memory is being leaked above. Even after making a call to sys$deltva f$getpi shows 0F2E0000 and after calling sys$mgblsce it increases it value to 1D5A2000.

2) When we are mapping the same global section again then why not it is being mapped at the same location of P0 which we have just freed above at step 4.

Hope I am clear in my questions. Please let me know if any clarification is required or if I have done some mistake.

Duncan Morris
Honored Contributor

Re: P0 space of memory leak


please read through this thread


which discusses the checkerboarding effect of repated allocation and deallocation of memory in a process.

It should help you understand what you are seeing in your own application.

Jon Pinkley
Honored Contributor

Re: P0 space of memory leak

If you want us to debug for you, you have to show us the code that isn't working.

Given no more info than what you have provided, my GUESS is that sect_mask has the SEC$M_EXPREG bit set.

From the SSREF $MGBLSC description:

"When the SEC$M_EXPREG flag is set, the second inadr longword is ignored, while bit 30 (the second most significant bit) of the first inadr longword is used to determine the region of choice. If the bit is clear, P0 is chosen; if the bit is set, P1 is chosen."

When that bit is set, and the inadr contains a P0 address, the virtual address used begins at the page above the highest current P0 page that is mapped.

It appears that something your program did after the first global section was mapped, allocated some space in P0. Look at the values that were returned in the first call, the highest address 254255103 decimal or 0xF279FFF <- Note high end of a page, when you mapped the second time the low end was at 254672896 decimal or 0xF2E0000 <- Note start of a new page)

So something mapped 417792 bytes (51 Alpha pages) after the address space that you mapped the first time.

237772800 bytes (29025 Alpha Pages) mapped first time
237772800 bytes (29025 Alpha Pages) mapped second time

Are you mapping different global sections each time through? If not, then why are you deleting the virtual address space, just to remap it? If it is a different global section, but every global section is the same size, then clear the SEC$M_EXPREG after the map it the first time, and just reuse the same address space that got returned the first time. If they are not all the same size, then you have a problem. You will have to allocate enough for the largest global section, and just reuse the space starting at the same base address.

it depends
Hein van den Heuvel
Honored Contributor

Re: P0 space of memory leak

in $CRMPSC you used, but failed to tell us about, the flag EXPREG and did not specify an exact address range. Correct?
So OpenVMS grows the end of P0 VA to accomodate the section.
The $DELTVA now unmaps the section freeing the address space but openVMS does not know whether the program intends to re-use that address range to map something else later

Rule: $DELTVA will reduce (shrink) the P0 VA end IF, and ONLY IF, the deltva range ends at the end... because in that case a future remap can always be accomodated.

To verify this do (F$ | SYS$) GETJPI for FREP0VA

What might have allocated memory after your section?
- LIB$GETVM / malloc. Workaround: pre-malloc / getvm all of what the program is expected to need in most circumstances, then immedaitly return for the program
- RMS internal structures (buffers, ifab, irab..). Woraround: increase SYSGEN IMGIOCNT and.or LINK with the IOSEGMENT option large enough for most usage

- RMS global buffers and file statistics blocks. They suffer from the same creep. Fixed in OpenVMS 8.2 where RMS starts to remember the sections = address ranges used.

So... the program may need to learn to remember some VA ranges.

Duncan, I believe that in the problem you reference the DELTVA and FREPoVA does nto play a role.

Hope this helps some,
Hein van den Heuvel (at gmail dot com)
HvdH Performance Consulting

John Gillings
Honored Contributor

Re: P0 space of memory leak


Since you don't have complete control over all allocations in P0 space, you can't predict how your $MGBLSC and $DELTVA will interact with the rest of virtual address space. As Hein has suggested, your intention won't work unless the VA you're deleting remains at the end of P0 space.

It may be better to allocate a chunk of P0 space large enough for your largest expected requirement, then map the global sections as required, reusing the same address space.

Alternatively, move the section into P2 space using $MGBLSC_64 and $DELTVA_64 (though I think I'd leave out the $DELTVA part, as it just makes things more complicated, and you're going to recreate the space immediately anyway).
A crucible of informative mistakes
Honored Contributor

Re: P0 space of memory leak

If it were not feasible to manage this without mapping and unmapping (and assuming you can't simply reserve and overwrite the same virtual range), I'd consider moving to a small herd of server processes, and away from virtual memory mapping. Keep a pool of server processes around as needed, communicate (via file or shared memory or mailbox or network or lock value block or ICC or whatever), and clean out virtual memory as required by cleaning out processes with $delprc or $forcex.

Moving to processes (and a network) means you can incrementally expand or contract capacity.