Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Releasing memory (continuation)
I "refresh" the thread
http://communities2.microsoft.com/c...b7-77f42b00681a

because many solutions have been proposed and I wanted to verify and give
results to the ng.

I verified objects collection vs objects array (no doubt about the fact that
UDTs array would be the fastest).

That's what appened working with 100000 instances:

OBJECTS COLLECTION
--------
Dim coll As New Collection

For i = 0 To 100000
coll.Add New myObject, CStr(i)
Next i
Allocation:  8 seconds


For i = 0 To 100000
coll.Remove CStr(i)
Next i
Release:    35 seconds


For i = 0 To 100000
coll.Remove 1
Next i
Release:    33 seconds


For i = 100000 To 0 Step -1
coll.Remove i
Next i
Killed after 2 minutes, only about 10000 objects released

For i = 100000 To 0 Step -1
coll.Remove CStr(i)
Next i
Release:    34 seconds

Set coll = Nothing
Release:    32 seconds


OBJECTS ARRAY
-------
Dim arr(100000) As myObject

For i = 0 To UBound(arr, 1)
Set arr(i) = New myObject
Next i
Allocation:  2 seconds

For i = 0 To UBound(arr, 1)
Set arr(i) = Nothing
Next i
Release:    17 seconds

For i = UBound(arr, 1) To 0 Step -1
Set arr(i) = Nothing
Next i
Release:    17 seconds

I also tried a dynamic array released by Redim arr(0); same elapsed as above
:
Allocation:  2 seconds
Release:    17 seconds

COMMENTS:

a) Arrays are very faster than Collections

b) Rank
1 - Set coll = Nothing
2 - Removing 1st ordinal item
3 - Removing in reversed key order
4 - Removing in key order
5 - Removing in reversed ordinal order (geologic time)

c) Release time in collection test seems to be spent 1/2 navigating thru the
collection, 1/2 releasing memory. Total time about 34 seconds, only 17
seconds the memory release time, as derived from array test (where non
navigation occurs).

d) It seems that nothing can speed up memory release of instances (arrays
perform better because there is no collection structure to navigate thru, bu
t
memory release time remains the same).

So one question remains I can't imagine the answer:

What does system do to release the process memory instantly when I kill the
process?

Many many many thanks for an answer.

PS
About Scripting.Dictionary:
I hope I will try soon

About SQL Server:
My in-memory DB is loaded from a disk database (MS Access).
I choose an in-memory structure to process data because of speed needs

Tank you nevertheless.

Report this thread to moderator Post Follow-up to this message
Old Post
nisant
09-28-04 01:55 PM


Re: Releasing memory (continuation)
Your last question is easy: It deletes the process and it's virtual address
space. If you kill the process with TerminateProcess then their is no
object-level cleanup, only very basic cleanup to release certain resources
back to the O/S.

The process heap(s) are process-specific. Memory is only returned to the
heap when it is explicitly deallocated, and may then be used to service
subsequent allocation requests within that process. When the process is
terminated, *all* the virtual address space is torn down: any physical
memory and paging file resources are returned to the O/S. It doesn't waste
time messing with stuff inside the heap because it was merely a process
entity.

However, if the process were terminated with a WM_CLOSE message then the
situation may be different. The application is then taking responsibility
for tearing down its own objects, and so the heap will be accessed.

Many systems allow memory to be allocated from separate heaps (sometimes
called zones). This has a number of advantages: In a multi-threaded
environment, each thread has items allocated from its own heap, thus
reducing thread contention (see the 'Hoard' memory allocator for instance).
Also, memory can be reclaimed in one operation by simply deleting the heap,
rather than returning every single memory packet back to a single heap.

Tony Proctor

"nisant" <nisant@discussions.microsoft.com> wrote in message
news:4BD578E1-9C58-421E-AA4F-BA7AEF6B1B84@microsoft.com...
> I "refresh" the thread
>
http://communities2.microsoft.com/c...b7-77f42b00681a
>
> because many solutions have been proposed and I wanted to verify and give
> results to the ng.
>
> I verified objects collection vs objects array (no doubt about the fact
that
> UDTs array would be the fastest).
>
> That's what appened working with 100000 instances:
>
> OBJECTS COLLECTION
> --------
> Dim coll As New Collection
>
>     For i = 0 To 100000
>         coll.Add New myObject, CStr(i)
>     Next i
> Allocation:  8 seconds
>
>
>     For i = 0 To 100000
>         coll.Remove CStr(i)
>     Next i
> Release:    35 seconds
>
>
>     For i = 0 To 100000
>         coll.Remove 1
>     Next i
> Release:    33 seconds
>
>
>     For i = 100000 To 0 Step -1
>         coll.Remove i
>     Next i
> Killed after 2 minutes, only about 10000 objects released
>
>     For i = 100000 To 0 Step -1
>         coll.Remove CStr(i)
>     Next i
> Release:    34 seconds
>
>     Set coll = Nothing
> Release:    32 seconds
>
>
> OBJECTS ARRAY
> -------
> Dim arr(100000) As myObject
>
>     For i = 0 To UBound(arr, 1)
>         Set arr(i) = New myObject
>     Next i
> Allocation:  2 seconds
>
>     For i = 0 To UBound(arr, 1)
>         Set arr(i) = Nothing
>     Next i
> Release:    17 seconds
>
>     For i = UBound(arr, 1) To 0 Step -1
>         Set arr(i) = Nothing
>     Next i
> Release:    17 seconds
>
> I also tried a dynamic array released by Redim arr(0); same elapsed as
above:
> Allocation:  2 seconds
> Release:    17 seconds
>
> COMMENTS:
>
> a) Arrays are very faster than Collections
>
> b) Rank
>     1 - Set coll = Nothing
>     2 - Removing 1st ordinal item
>     3 - Removing in reversed key order
>     4 - Removing in key order
>     5 - Removing in reversed ordinal order (geologic time)
>
> c) Release time in collection test seems to be spent 1/2 navigating thru
the
> collection, 1/2 releasing memory. Total time about 34 seconds, only 17
> seconds the memory release time, as derived from array test (where non
> navigation occurs).
>
> d) It seems that nothing can speed up memory release of instances (arrays
> perform better because there is no collection structure to navigate thru,
but
> memory release time remains the same).
>
> So one question remains I can't imagine the answer:
>
> What does system do to release the process memory instantly when I kill
the
> process?
>
> Many many many thanks for an answer.
>
> PS
> About Scripting.Dictionary:
> I hope I will try soon
>
> About SQL Server:
> My in-memory DB is loaded from a disk database (MS Access).
> I choose an in-memory structure to process data because of speed needs
>
> Tank you nevertheless.



Report this thread to moderator Post Follow-up to this message
Old Post
Tony Proctor
09-28-04 01:55 PM


Re: Releasing memory (continuation)

"Tony Proctor" wrote:

>......
> Also, memory can be reclaimed in one operation by simply deleting the heap
,
> rather than returning every single memory packet back to a single heap.
>

Very interesting.

I tried on the fly to use these informations in my test, via API, getting
process heap handle (GetProcessHeap) before in-memory DB loading and trying
to free the mamory destroying the heap before program termination.

Running this in IDE, VB crashed.
I suppose I destroyed the IDE heap as well.

Running in a generated .exe program I observed the usual slow memory release
.

Trivial approach to the problem, I know.

But do you think it's possible, in a VB program, to force a fast release
using memory API?
In other words allocate a large chunks of address space, use it to store my
collection of objects, then instantly free memory and reallocate it if
necessary for another collection allocation ?


Report this thread to moderator Post Follow-up to this message
Old Post
nisant
09-28-04 01:55 PM


Re: Releasing memory (continuation)
Hi,

nisant schrieb:
>
> "Tony Proctor" wrote:
> 
>
> Very interesting.
>
> I tried on the fly to use these informations in my test, via API, getting
> process heap handle (GetProcessHeap) before in-memory DB loading and tryin
g
> to free the mamory destroying the heap before program termination.
>
> Running this in IDE, VB crashed.

No wonder.

> I suppose I destroyed the IDE heap as well.
>
> Running in a generated .exe program I observed the usual slow memory relea
se.
>
> Trivial approach to the problem, I know.
>
> But do you think it's possible, in a VB program, to force a fast release
> using memory API?
> In other words allocate a large chunks of address space, use it to store m
y
> collection of objects, then instantly free memory and reallocate it if
> necessary for another collection allocation ?

No, you can't. It is VB which decides where to store the objects.

But you can decide, where the object *pointers* go, but this would not
help either.

One thing should be possible, but its awful:

Set all individual object references to zero using RtlFillMemory. If in
a collection, set the collections pointer to zero. But as said, this is
awful, nearly as awful as killing the process. And it should be done
only when you are finished with your app. Don't use it to create and
destroy objects intermediately. Better don't use it at all :-)

If you want to have objects in a memory space where you have your hands
on, use Curlands lightweight objects.

Or better (as easier), use UDTs. Create one UDT and one wrapper class
per DB table. Put all the table's records in an array of UDTs. The
wrapper class then gives transparent access to the records. If done
right, there should be no difference in accessing the records when using
one class instance per record (as you probably do now) or a wrapper
class for all records, besides some index value in the accessing
methods. Even this can be omitted if you set the index, using a separate
property, before accessing a records data. And the wrapper objects can
be held in a collection, if you want to.

Sorry, but your current design (using hundreds of thousands of classic
VB class instances) is not suitable for VB. You should change it.

--
Ulrich Korndoerfer

VB tips, helpers, solutions -> http://www.proSource.de/Downloads/


Report this thread to moderator Post Follow-up to this message
Old Post
Ulrich Korndoerfer
09-28-04 08:55 PM


Re: Releasing memory (continuation)
Thank you, Ulrich, for your "inexorable" analysis.

Now I know what I can do using VB and what I can't dealing with objects
instances.

"Ulrich Korndoerfer" wrote:

> Hi,
>
> nisant schrieb: 
>
> No wonder.
> 
>
> No, you can't. It is VB which decides where to store the objects.
>
> But you can decide, where the object *pointers* go, but this would not
> help either.
>
> One thing should be possible, but its awful:
>
> Set all individual object references to zero using RtlFillMemory. If in
> a collection, set the collections pointer to zero. But as said, this is
> awful, nearly as awful as killing the process. And it should be done
> only when you are finished with your app. Don't use it to create and
> destroy objects intermediately. Better don't use it at all :-)
>
> If you want to have objects in a memory space where you have your hands
> on, use Curlands lightweight objects.
>
> Or better (as easier), use UDTs. Create one UDT and one wrapper class
> per DB table. Put all the table's records in an array of UDTs. The
> wrapper class then gives transparent access to the records. If done
> right, there should be no difference in accessing the records when using
> one class instance per record (as you probably do now) or a wrapper
> class for all records, besides some index value in the accessing
> methods. Even this can be omitted if you set the index, using a separate
> property, before accessing a records data. And the wrapper objects can
> be held in a collection, if you want to.
>
> Sorry, but your current design (using hundreds of thousands of classic
> VB class instances) is not suitable for VB. You should change it.
>
> --
> Ulrich Korndoerfer
>
> VB tips, helpers, solutions -> http://www.proSource.de/Downloads/
>
>

Report this thread to moderator Post Follow-up to this message
Old Post
nisant
09-29-04 01:55 PM


Re: Releasing memory (continuation)
"Ulrich Korndoerfer" <ulrich_wants_nospam@prosource.de> wrote

> Or better (as easier), use UDTs. Create one UDT and one wrapper class
> per DB table. Put all the table's records in an array of UDTs. The
> wrapper class then gives transparent access to the records.

Does everyone else recognise that as the flyweight pattern?

I was just thinking that giving it a name, might make it easier to talk abou
t,
later on.....

LFS

Report this thread to moderator Post Follow-up to this message
Old Post
Larry Serflaten
09-29-04 01:55 PM


Re: Releasing memory (continuation)
Hi,

Larry Serflaten wrote:
>
> "Ulrich Korndoerfer" <ulrich_wants_nospam@prosource.de> wrote
> 
>
> Does everyone else recognise that as the flyweight pattern?

How did it come that you did think to recognise it? To your info, it is
not. Actually, the info given from my statement above is very little.
But not little enough to see, that it can not be the flyweight pattern
;-)

I gave just a hint how one could proceed. Of course the base of this
hint is: minimize the number of objects.
Instead creating one object for each table record (an object which
carries the record data as internal state), try to use fewer objects
(fewer than record count).

One method could be (and this it what I intended with my hint without
going to deep at this point, as I don't know if the OP is interested
in):

Make one object, which contains *all* records in its internal state.
This could be a self made collection, which eg could hand out data using
the records primary key as the collection key. And does contain some
handy methods (like loading a record from the DB, allow changes to the
record, storing changed record back to the DB, do a selection based on
some filter criteria and so on).

This should already be mighty enough. Now it depends on the OP needs
(which I don't know) if he should go further. If he needs concurrent
access from several clients to the records, then the flyweight pattern
could have benefits. But the flyweight pattern is more complicated to
implement, so in the first step I did not suggest it. The flyweight
pattern needs the implementation of a class factory producing the
flyweights and of course the flyweight too.

The flyweight idea is to hold the data (the records) in external state
(outside of any object) and to create and hand out (on demand on the
factory) a flyweight instance bound (by a data pointer) to a currently
to be processed individual record. The flyweight would implement pretty
much the same functionality as my one for all object from above (except
of filtering, as a flyweight is responsible for only one of the
records): load record from database, allow changes to the records (via
flyweight properties), store back to DB and so on. If a concurrent user
wants access to the same record, the class factory does not create a new
instance but hands out the already created one.

So the amout of objects is reduced too (but there would be eventually
more than one being around at the same time). But it seems to me that
flyweights are not so good on typical database tasks.




--
Ulrich Korndoerfer

VB tips, helpers, solutions -> http://www.proSource.de/Downloads/


Report this thread to moderator Post Follow-up to this message
Old Post
Ulrich Korndoerfer
09-29-04 01:55 PM


Re: Releasing memory (continuation)
If the UDT contains variable-length String fields then you have a similar
memory deallocation performance hit when the array is deleted

Tony Proctor

"Ulrich Korndoerfer" <ulrich_wants_nospam@prosource.de> wrote in message
news:415A964B.5856DC9B@prosource.de...
> Hi,
>
> Larry Serflaten wrote: 
>
> How did it come that you did think to recognise it? To your info, it is
> not. Actually, the info given from my statement above is very little.
> But not little enough to see, that it can not be the flyweight pattern
> ;-)
>
> I gave just a hint how one could proceed. Of course the base of this
> hint is: minimize the number of objects.
> Instead creating one object for each table record (an object which
> carries the record data as internal state), try to use fewer objects
> (fewer than record count).
>
> One method could be (and this it what I intended with my hint without
> going to deep at this point, as I don't know if the OP is interested
> in):
>
> Make one object, which contains *all* records in its internal state.
> This could be a self made collection, which eg could hand out data using
> the records primary key as the collection key. And does contain some
> handy methods (like loading a record from the DB, allow changes to the
> record, storing changed record back to the DB, do a selection based on
> some filter criteria and so on).
>
> This should already be mighty enough. Now it depends on the OP needs
> (which I don't know) if he should go further. If he needs concurrent
> access from several clients to the records, then the flyweight pattern
> could have benefits. But the flyweight pattern is more complicated to
> implement, so in the first step I did not suggest it. The flyweight
> pattern needs the implementation of a class factory producing the
> flyweights and of course the flyweight too.
>
> The flyweight idea is to hold the data (the records) in external state
> (outside of any object) and to create and hand out (on demand on the
> factory) a flyweight instance bound (by a data pointer) to a currently
> to be processed individual record. The flyweight would implement pretty
> much the same functionality as my one for all object from above (except
> of filtering, as a flyweight is responsible for only one of the
> records): load record from database, allow changes to the records (via
> flyweight properties), store back to DB and so on. If a concurrent user
> wants access to the same record, the class factory does not create a new
> instance but hands out the already created one.
>
> So the amout of objects is reduced too (but there would be eventually
> more than one being around at the same time). But it seems to me that
> flyweights are not so good on typical database tasks.
>
>
>
>
> --
> Ulrich Korndoerfer
>
> VB tips, helpers, solutions -> http://www.proSource.de/Downloads/
>



Report this thread to moderator Post Follow-up to this message
Old Post
Tony Proctor
09-29-04 01:55 PM


Re: Releasing memory (continuation)
"Ulrich Korndoerfer" <ulrich_wants_nospam@prosource.de> wrote
 
>
> How did it come that you did think to recognise it?

You described a situation that had external data (the array of UDTs)
and one object that gives access to the records.  That lead me to think
that object would contain properties to view and modify one record
at a time, (much like a cursor).

There are sub-classes of the flyweight pattern that are not shared, or
do not use a factory.  While the typical flyweight pattern may be thought
of as passing out many copies of external data, and using a factory to
get a new reference, I have always associated this sort of access to be
under the definition of the flyweight pattern too.  The object would
maintain no state of its own, and would only return data from the
UDTs or perform calculations on that data, and return the result.

If not the flyweight pattern, then what?

LFS

Report this thread to moderator Post Follow-up to this message
Old Post
Larry Serflaten
09-29-04 01:55 PM


Re: Releasing memory (continuation)
Hi,

Tony Proctor wrote:
>
> If the UDT contains variable-length String fields then you have a similar
> memory deallocation performance hit when the array is deleted
>
>             Tony Proctor

The deallocation costs are not similar. See this little test:

Times in ms on my system for destroying an array of simplest (no code in
them, just plain empty class) objects by erasing the array, and times
needed for destroying an array holding strings of varying content and
length of about 100 chars, which are 200 bytes at least, and such
consuming more memory than the objects (which consume about 100 bytes
per instance), are:

Element count N Object array String array

1000                      6            1
2000                     13            2
4000                     33            6
8000                   ~110           12
16000                   ~750           25
32000                  ~3300           50
64000                 ~13200          103

Creation methods were:

For i = 1 To N
s(i) = CStr(i) & String$(100, "*")
Next i

For i = 1 To N
Set c(i) = New Class1
Next i

and deallocation methods were:

Erase s
Erase c


Deallocation time for strings is linear to N, deallocation of objects
(despite the fact that in this test case they consume much less memory
than the strings), is nearly quadratic (at least for object counts
greater 10000). As mentioned in my earlier posts, this quadratic
behaviour is it what makes using large numbers of objects in VB
infeasible.

To my knowledge, memory for strings is manged by the OLE runtimes, not
VB itself. This then might explain the difference.

--
Ulrich Korndoerfer

VB tips, helpers, solutions -> http://www.proSource.de/Downloads/


Report this thread to moderator Post Follow-up to this message
Old Post
Ulrich Korndoerfer
09-29-04 01:55 PM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

Visual Basic archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 05:33 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.