Board index » delphi » Global Memory

Global Memory

Is there any way to free up global memory? For instance if I read a big
record from a file and then, later in the program, I decide I don't want
it, how can I remove it? Or should I just forget that and use pointers?

 

Re:Global Memory


Quote
> Is there any way to free up global memory? For instance if I read a big
> record from a file and then, later in the program, I decide I don't want
> it, how can I remove it? Or should I just forget that and use pointers?

   If the record area is a variable in the Data Segment (a declared Var),
no, you can't "remove it" - the Data Segment is there for the the entire
execution.  However, you can redefine that space in your source, with the
"absolute" clause, and you can use it for another purpose, in another
way.
   More to the point, the way I'd do what you seem to want is allocate
the space on the Heap (with a pointer) and deallocate it when/if no
longer needed.

Re:Global Memory


Quote
Mike Copeland wrote:

> > Is there any way to free up global memory? For instance if I read a big
> > record from a file and then, later in the program, I decide I don't want
> > it, how can I remove it? Or should I just forget that and use pointers?

>    If the record area is a variable in the Data Segment (a declared Var),
> no, you can't "remove it" - the Data Segment is there for the the entire
> execution.  However, you can redefine that space in your source, with the
> "absolute" clause, and you can use it for another purpose, in another
> way.
>    More to the point, the way I'd do what you seem to want is allocate
> the space on the Heap (with a pointer) and deallocate it when/if no
> longer needed.

Neat. That's what I was thinking. In all actuality, I wanted to read the
record to the global memory and a pointer and when the program exits,
only write the record back to disk if the record variable and the record
pointer were different (the record has been changed). Is this the best
way of going about something like this or should I read the record as 2
different pointers? Also, how do I compare records? RecordVAR =
RecordPTR^ didn't work. Will I have to compare the data fields one at a
time to see if the records are the same? Thanks

Re:Global Memory


Quote
>Is there any way to free up global memory? For instance if I read a big
>record from a file and then, later in the program, I decide I don't want
>it, how can I remove it? Or should I just forget that and use pointers?

  What do you call Global Memory? DOS programs don't need to dispose the
allocated memory region, because on return it'll be freed by DOS. However
it's a good maner to free up memory using FreeMem(Pointer, Size).

  Under Windows the memory allocated by GlobalAlloc must be returned to
the system via GlobalFree (MemHandle).

Regards,
Alex

Re:Global Memory


Quote
> >    More to the point, the way I'd do what you seem to want is allocate
> > the space on the Heap (with a pointer) and deallocate it when/if no
> > longer needed.

> Neat. That's what I was thinking. In all actuality, I wanted to read the
> record to the global memory and a pointer and when the program exits,
> only write the record back to disk if the record variable and the record
> pointer were different (the record has been changed). Is this the best
> way of going about something like this or should I read the record as 2
> different pointers?

   Classically, you must keep some flag in the record (or elsewhere"
which is updated whenever the "record" is changed.  That's what should
tell you to write it out.  Reading it in and copying into another memory
area (and trying to compare both) is needless overkill...and quite
expensive, too.  A simple boolean/bit flag is all you need, as well as
common "update" code which sets it whenever a field in the record is
changed.

Also, how do I compare records? RecordVAR =

Quote
> RecordPTR^ didn't work. Will I have to compare the data fields one at a
> time to see if the records are the same? Thanks

   You can't compare variables of structured data types (records, arrays,
etc.) at that level - you must compare specific elements, as needed for
what must be tested.  It's often too expensive to do so - assuming you
even could in Pascal - which is another reason the "update flag" is
useful.

Re:Global Memory


-=[ In:myacco...@glas.apc.org was heard to say... ]=-

 >Is there any way to free up global memory? For instance if I read a big
 >record from a file and then, later in the program, I decide I don't want
 >it, how can I remove it? Or should I just forget that and use pointers?

 In> What do you call Global Memory? DOS programs don't need to dispose
 In> the  allocated memory region, because on return it'll be freed by DOS.
 In> However  it's a good maner to free up memory using FreeMem(Pointer,
 In> Size).

Well, yes, but only if you're using GetMem() to allocate it in the first
place, and only if you're NOT using Mark/Release. There is New(), which
requires Dispose() to deallocate, and FreeMem() won't work if you're trying
to free memory that was allocated with New().

And then there is Mark() and Release(), which will allow you to allocate
with New() or GetMem(), but with which you should NEVER use Dispose() or
FreeMem(). Mark and Release are great for blanket deallocations covering
all memory between to addresses, but their use is quite limiting.

        -- Kim Forwood --

  /-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-\
  $           Kim Forwood  <kim.forw...@access.cn.camriv.bc.ca>          %
  %              http://goodship.cn.camriv.bc.ca/~kforwood/              $
  $         For what purpose is life, if one cannot live freely?         %
  \-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-/

___ Blue Wave/QWK v2.20

Re:Global Memory


Well Kim,

if i may comment on that. I cannot and will not recommend the use of
mark/release to anyone. I think if one wants to write some decent code that
is readable you should use new/dispose. The freemem/getmem scheme i use
mostly for dynamic arrays and stuff...

Cheers
Anco

Re:Global Memory


-=[ In:a...@dds.nl was heard to say... ]=-

 In> Well Kim,

 In> if i may comment on that. I cannot and will not recommend the use of
 In> mark/release to anyone. I think if one wants to write some decent code
 In> that is readable you should use new/dispose. The freemem/getmem scheme
 In> i use mostly for dynamic arrays and stuff...

You really should quote, at least the full name or address of the person
you are responding to. Anyway...

I was not suggesting that anyone use Mark/Release. I was merely pointing
out that freeing up memory can be done in several ways, of which Mark/Release
are one. The person I was responding to had been rather vague and seemed to
be making the inference that FreeMem will deallocate memory no matter how
that memory was allocated. My post was meant to clear that up, and to make
mention of the other methods that can be used (I do agree however that use
of Mark/Release is not a good idea in most cases).

Furthermore, it's not a good idea to say that someone should use any one
method of allocation/deallocation over another, such as you do above. Each
situation is different, and depending on the structure of the data, one
might find that New/Dispose just isn't adequate. The same goes with
GetMem/FreeMem.

        -- Kim Forwood --

  /-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-\
  $           Kim Forwood  <kim.forw...@access.cn.camriv.bc.ca>          %
  %              http://goodship.cn.camriv.bc.ca/~kforwood/              $
  $         For what purpose is life, if one cannot live freely?         %
  \-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-/

___ Blue Wave/QWK v2.20

Re:Global Memory


Quote
> In> What do you call Global Memory? DOS programs don't need to dispose
> In> the  allocated memory region, because on return it'll be freed by DOS.
> In> However  it's a good maner to free up memory using FreeMem(Pointer,
> In> Size).

>Well, yes, but only if you're using GetMem() to allocate it in the first
>place, and only if you're NOT using Mark/Release. There is New(), which
>requires Dispose() to deallocate, and FreeMem() won't work if you're trying
>to free memory that was allocated with New().

   I agree with you, Kim. But what I have just tried is this code that
works fine on TP7.0:

type
   Rec = record
     Field: Word;
   end;

var
  P: ^Rec;

begin
  New (P);
  FreeMem(P, SizeOf(Rec));  { :) }

  GetMem(P, SizeOf(Rec));
  Dispose(P);               { :) }
end.

  Or something will be wrong with memory on exit?

Regards,
Alex

Re:Global Memory


In article <01bba146$c88bac00$640286c2@fibonacci>
Anco Scholte ter Horst wrote:

Quote
>Well Kim,

>if i may comment on that. I cannot and will not recommend the use of
>mark/release to anyone. I think if one wants to write some decent codethat
>is readable you should use new/dispose. The freemem/getmem scheme iuse
>mostly for dynamic arrays and stuff...

Mark/Release is a tool, and like all tools it is a perfect fit for
certain situations.  I suggest that your prejudice against these
statements is simply a matter of never having been in a situation
that can benefit from their use.

Picture an application that processes large amounts of data.  Assume
the data is read as records and that as much data as possible is
loaded into the heap, and once it is examined/processed, the data is
utterly useless and needs to be abandoned and the next block can be
read into memory.  

Consider the time it will take to dispose each record versus using a
single release statement.  It's not just a matter of issuing dispose
10,000 times.  For each dispose the heap manager must search its list
of unused blocks to properly position each block and determine if the
block can be merged with previously released blocks.  This becomes a
substantial piece of overhead, especially if the order that memory
was allocated was lost as the records were processed.  Release OTOH,
simply stores the "released" address to HeapPtr and sets its unused
list to nil.  

Mark/Release is a good tool for managing the heap when memory is to
be "released" in the reverse order to which it was allocated. Granted
that this may be rare as most applications depend upon the ability to
randomly dispose regardless of the order that allocations were made.

BTW, since you seldom quote anything from the article to which you
are replying, unless I am lucky enough to retrieve the two articles
at the same time, I seldom know what you are talking about.  Without
a reasonable frame of reference, even the best reply is rendered
useless.

    ...red

Re:Global Memory


-=[ In:myacco...@glas.apc.org was heard to say... ]=-

 > In> What do you call Global Memory? DOS programs don't need to dispose
 > In> the  allocated memory region, because on return it'll be freed by DOS.
 > In> However  it's a good maner to free up memory using FreeMem(Pointer,
 > In> Size).
 >
 >Well, yes, but only if you're using GetMem() to allocate it in the first
 >place, and only if you're NOT using Mark/Release. There is New(), which
 >requires Dispose() to deallocate, and FreeMem() won't work if you're trying
 >to free memory that was allocated with New().

 In> I agree with you, Kim. But what I have just tried is this code that
 In> works fine on TP7.0:

 In> type
 In> Rec = record
 In> Field: Word;
 In> end;

 In> var
 In> P: ^Rec;

 In> begin
 In> New (P);
 In> FreeMem(P, SizeOf(Rec));  { :) }

 In> GetMem(P, SizeOf(Rec));
 In> Dispose(P);               { :) }
 In> end.

 In> Or something will be wrong with memory on exit?

 In> Regards,
 In> Alex

That may work, but I wouldn't trust it at all! It could very well mess up
the heap manager, and eventually crash the system or worse.

        -- Kim Forwood --

  /-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-\
  $           Kim Forwood  <kim.forw...@access.cn.camriv.bc.ca>          %
  %              http://goodship.cn.camriv.bc.ca/~kforwood/              $
  $         For what purpose is life, if one cannot live freely?         %
  \-=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=--=oOo=-/

___ Blue Wave/QWK v2.20

Re:Global Memory


Quote
Kim.Forw...@access.cn.camriv.bc.ca (Kim Forwood) wrote:
>-=[ In:myacco...@glas.apc.org was heard to say... ]=-
> > In> What do you call Global Memory? DOS programs don't need to dispose
> > In> the  allocated memory region, because on return it'll be freed by DOS.
> > In> However  it's a good maner to free up memory using FreeMem(Pointer,
> > In> Size).

> >Well, yes, but only if you're using GetMem() to allocate it in the first
> >place, and only if you're NOT using Mark/Release. There is New(), which
> >requires Dispose() to deallocate, and FreeMem() won't work if you're trying
> >to free memory that was allocated with New().
> In> I agree with you, Kim. But what I have just tried is this code that
> In> works fine on TP7.0:
> In> type
> In> Rec = record
> In> Field: Word;
> In> end;
> In> var
> In> P: ^Rec;
> In> begin
> In> New (P);
> In> FreeMem(P, SizeOf(Rec));  { :) }
> In> GetMem(P, SizeOf(Rec));
> In> Dispose(P);               { :) }
> In> end.
> In> Or something will be wrong with memory on exit?
> In> Regards,
> In> Alex
>That may work, but I wouldn't trust it at all! It could very well mess up
>the heap manager, and eventually crash the system or worse.

It wouldn't mess up the heap manager at all.

type
  TDumRec = record
      A : Integer;
      B : LongInt;
    end;
  PDumRec = ^TDumRec;

var
  DPtr : PDumRec;

begin
  GetMem( DPtr, sizeof( TDumRec));
{ Assembler trace
  push   0006
  call   378F:012D
  mov    [TEST.DPTR], ax
  mov    [005E], dx

Quote
}

  FreeMem( DPtr, sizeof( TDumRec));
{
  push  word ptr [005E]
  push  word ptr [TEST.DPTR]
  push  0006
  call  378F:0147
Quote
}

  new( DPtr);
{
  push  0006
  call  378F:012D
  mov   [TEST.DPTR], ax
  mov   [005E], dx
Quote
}

  dispose( DPtr);
{
  push  word ptr [005E]
  push  word ptr [TEST.DPTR]
  push  0006
  call  378F:0147
Quote
}

end.

Do you see a big difference? ?If you check RTL you wouldn't find any
traces of GetMem/FreeMem. Actually GetMem/FreeMem/new/dispose are not
functions - they are converted by compiler to two function calls (I
can't recall right names and don't have RTL nearby) as Write() does.
This example was compiled in BPW, but I don't think it'll make any
difference under DOS (or PM???).

Cheers
  Dmitri

--------------------------------------------------------------
        Shit happens, but why it always happens to us?
--------------------------------------------------------------
Dmitri Poujlivyi            mailto:  dmi...@god.bel.alcatel.be
                            http://www.dma.be/p/bewoner/dmitri

Re:Global Memory


In a previous article, R. E. Donais <RDon...@gnn.com> wrote:

Quote

>In article <01bba146$c88bac00$640286c2@fibonacci>
>Anco Scholte ter Horst wrote:

>>Well Kim,

>>if i may comment on that. I cannot and will not recommend the use of
>>mark/release to anyone. I think if one wants to write some decent codethat
>>is readable you should use new/dispose. The freemem/getmem scheme iuse
>>mostly for dynamic arrays and stuff...

>Mark/Release is a tool, and like all tools it is a perfect fit for
>certain situations.  I suggest that your prejudice against these
>statements is simply a matter of never having been in a situation
>that can benefit from their use.

[good argument in favor of Mark/Release in some situations cut - follow
  the thread if you want to read it.]

I sometimes find using Mark/Release to be a good safety
feature:  if I have a complicated process that uses a lot of dynamic
memory allocation and I _KNOW_ that there is no reason not to make
sure that the heap is returned to the state it had before I started
that process, I'll call "Mark" before and "Release" after running
the process.  In virtually every case I do something like this, I
_HOPE_ that the call to Release does nothing because I managed to
pair up every GetMem with a FreeMem (and every New with a Dispose).

However, the use of Mark and Release protects me from any cases where
I missed out on pairing a dynamic memory allocation with the proper
de-allocation.  And when I'm using someone else's code it protects me
from any such lapses on their part.  Sometimes I don't have source code
for units I need to use: only a .tpu file and some documentation  so
that I can't fix any memory problems I do find.  

As an example, I have a program that executes 300 K of code
over and over ...

   While not Terminating_Condition do
   begin
      Mark(Heap_at_start_of_process);

      Run_Process;

      If HeapMark <> Heap_at_start_of_process
      then Log_the_heap_error;

       Release(Heap_at_start_of_process);
   end;

Rob

Other Threads