Memory Dump on Closure

Zeul
01-30-2007, 04:45 PM
I have a particularly hard problem.

My project contains dozens of collections / types / linked classes (ie a.b.c etc ). This is a significant amount of data that at present i dump to a txt file, and then when required read back in to repopulate the vars /trees.

For the quantity of data this can create huge files and the read in can be very slow (when you are upto a million lines!!) (btw this is already as compact as it can be)

What i need is a faster approach and i was thinking about a physical memory dump into a binary file of all the memory used by the app. When re-opening, this binary file is then 'reloaded' back into the memory; effectively restoring the 'state' of the program.

I know this is possible, because others apps do it.

I have never dealt with direct memory allocation. (apart from CopyMemory API) What is the best approach to this?

Thanks in advance.

Zeul
02-02-2007, 04:48 AM
Any help would be appreciated

Flyguy
02-02-2007, 06:13 AM
I don't think it's possible.
There is no such thing possible as a physical memory dump and reload it.
Certainly not when dealing with classes/objects.

What you have to try is to find a way to store the data in a binary file format so that you don't have to parse ascii files, this helps a lot.

What I would do is creating an UDT structure for every class.
This structure can be returned by the class and then saved to disk. When reading the structure from disk you pass it to the class and rebuild the properties.

Very basic, untested sample:

' Mod UDT
Option Explicit

Public Type tpHuman
iAge As Integer
sSurName As String
End Type


' Class Human
Option Explicit

Private m_iAge As Integer
Private m_sSurName As String

Public Property Let Age(ByVal iValue As Integer)
m_iAge = iValue
End Property

Public Property Get Age() As Integer
Age = m_iAge
End Property

Public Property Let SurName(ByVal sValue As String)
m_sSurName = sValue
End Property

Public Property Get SurName() As String
SurName = m_sSurName
End Property

Friend Function ToUDT() As tpHuman
With ToUDT
.iAge = Age
.sSurName = SurName
End With
End Function

Friend Function FromUDT(myHuman As tpHuman)
With myHuman
Me.Age = .iAge
Me.SurName = .sSurName
End With
End Function


' Class Humans
Option Explicit

Private m_cHumans As Collection

Public Function Add(sSurName As String, iAge As Integer) As clsHuman
Dim cHuman As clsHuman

Set cHuman = New clsHuman
cHuman.SurName = sSurName
cHuman.Age = iAge

m_cHumans.Add cHuman

Set Add = cHuman
End Function

Public Sub SaveHumans(ByVal sFileName As String)
Dim iID As Integer
Dim cHuman As clsHuman

' Remove existing file first
If Len(Dir$(sFileName)) > 0 Then Kill sFileName

' Get file ID
iID = FreeFile

' Create file
Open sFileName For Binary As iID
' Store the number of humans
Put #iID, , CLng(m_cHumans.Count)
' Traverse the human collection
For Each cHuman In m_cHumans
' Convert class to UDT and save
Put #iID, , cHuman.ToUDT
Next cHuman
Close iID
End Sub

Public Sub LoadHumans(ByVal sFileName As String)
Dim iID As Integer
Dim cHuman As clsHuman
Dim tHuman As tpHuman
Dim lNofHumans As Long, l As Long

' Create a new population
Set m_cHumans = New Collection

iID = FreeFile
Open sFileName For Binary As iID
' Get the number of humans
Get #iID, , lNofHumans
For l = 1 To lNofHumans
' Load the human UDT
Get #iID, , tHuman
' Create a new human
Set cHuman = New clsHuman
' Recreate it from UDT
cHuman.FromUDT tHuman
' Add to the population
m_cHumans.Add cHuman
Next l
Close iID
End Sub

Private Sub Class_Initialize()
Set m_cHumans = New Collection
End Sub

Zeul
02-02-2007, 01:07 PM
Thanks Flyguy.
I will look at this code in depth. I have a lot of collections that 'branch' off other collections eg

test.next.nowthis
test.next1.nowthis
test.next1.nowthis1 etc etc

test2.next.nowthis
and so on....

Also ome of the variables within each collection are arrays of no fixed size, so each 'test' will be of a different size and in the above example 'nowthis' may not be even present ie Nothing. Can each 'test' be 'put' into the binary file in its entirety (inc all sub collectins) or would i need to do a 'for each next in test.next' and so forth, and then 'put' that collection into the file.

I suppose the start of each 'test' could be signified by a special marker in the binary file, and then a unique marker for each nested collection.

Assuming the above would work, the dynamic arrays would be a problem. Could this be overcome by making sure that the array is the final entry in the UDT.

I have a similar issue to a bunch of Types.

Type tColl
a as integer
b as string
End Type

Type B
c() as tColl
End Type

Public thisTestColl() As B

These would also need to be 'dumped'.

phew this is going to take some testing!

Also i am just about to port my entire project over to VB 2005 (8.0), using the .Net framework. Would this methodology still hold true on this new platform?

Many thanks

Flyguy
02-02-2007, 02:45 PM
Shouldn't be to hard using nesting UDT, it's what I do all of the time.

Ofcourse the idea should apply to almost all programming languages.

Zeul
02-03-2007, 12:25 AM
Thanks

Zeul
02-06-2007, 07:08 AM
Thanks for your advice. I have managed to get nested UDT's saving and loading from a binary file. It is much faster.

Now to work on the collections (of which i have numerous and all interlinked!).

Also can something similar be done with a treeview control. My treeviews have thousands of nodes. Loading the info from the binary is very fast, but building the treeview slows it down - can the entire treeview be put into a binary also?

Flyguy
02-06-2007, 07:12 AM
How do you walk through your nodes in the tree?
Building/saving should be faster then Loading/creating the tree.

Zeul
02-06-2007, 09:32 AM
I am loading the tree with a normal:

for i = ubound(...)
treeview1.add blah blah
next

but i was wondering if the tree could be saved in its entirety and then do something like:

dim test as treeview??
get #1,, test

set treeview1 = test

could something like this be done?

Flyguy
02-06-2007, 02:11 PM
No, because it's an object with references to other objects.
There is no way to tell where in memory all these objects are stored.

Zeul
02-07-2007, 04:45 AM
My bad with the treeview. I accidently left in some processing of each node as it was created - as soon as that was removed the tree built almost instantly :D

But now back to the collections. Must a UDT be created for every collection (i have ~ 25 interlinked). If so, would the procedure be to:

for each human in cHuman
clshuman.savehuman filename
for each nextcollection in human.cNextCollection
clsNextCollection.savenextcollection filename

etc etc

and the reverse to reload?

Flyguy
02-07-2007, 05:13 AM
That would be the global process I had in mind.

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum