Hello Everyone,
I have create a small ole automation dll server program based on the vs6 project template
'MFC AppWizard (Dll)'
From this body project, I have created the following creatable CCmdTarget objects
CProject
CWorkspaces(Add, RemoveAll, Count, Item)
CWorkspace
CMeasurements(Add, RemoveAll, Count, Item)
CMeasurement (Name property, type of BSTR)
CWorkspaces and CMeasurements are just based on the MFC collection CPtrArray to collect the IDispatch pointers where an AddRef has been applied to avoid object destruction in vb6.
If I create the following vb6 code, I have the effect bellow:
Private Sub GenerateObject()
Dim lChannel As Long
Dim Meas As DummyWsdll.Measurement
Dim SubMeas As DummyWsdll.Measurement
Dim Ws As DummyWsdll.Workspace
Command1.Enabled = False
Set Ws = New DummyWsdll.Workspace
For lChannel = 1 To 24
Set Meas = New DummyWsdll.Measurement
Meas.Name = "Spectrum(Channel" & CStr(lChannel) & ",Channel" & CStr(lChannel)
For lBlock = 1 To 1000
Set SubMeas = New DummyWsdll.Measurement
SubMeas.Name = "Spectrum(Channel" & CStr(lChannel) & ",Channel" & CStr(lChannel)
Meas.Measurements.Add SubMeas
Set SubMeas = Nothing
Next lBlock
Ws.Measurements.Add Meas
Set Meas = Nothing
Next lChannel
gProject.Workspaces.Add Ws
End Sub
In the form load, I initialize the global gProject as follow:
Set gProject = New DummyWsdll.Project
Before I run the vb6 program, I looked at the Task Manager and the memory usage is at:
35.132Kb
If I run several time the GenerateObject routine, I go to :
41.332Kb (Run 1)
47.000Kb (Run 2)
52.772Kb (Run 3)
Here comes the effect. If I run the clean all operation:
gProject.Workspaces.RemoveAll
The memory usage returns to 37.448Kb.
So I am loosing +- 2Mb and this is also related to the number of runs I do.
I investigated the implemented objects and I decided to remove the .Name property from the CMeasurement
What was my suprise to see the memory was really stable when I return back after a RemoveAll().
On internet, I discovered SetOaNoCache which is apparently used to disable the BSTR cache effect.
As I am using VS6, I will have to call it as follow:
typedef int (*SETOANOCACHE)(void);
void DisableBSTRCache()
{
HINSTANCE hLib = LoadLibrary("OLEAUT32.DLL");
if (hLib != NULL) {
SETOANOCACHE SetOaNoCache = (SETOANOCACHE)GetProcAddress(hLib, "SetOaNoCache");
if (SetOaNoCache != NULL)
SetOaNoCache();
FreeLibrary(hLib);
}
}
I thought this could help me but that did not cover my issue.
I saw also this could be set in the Environment variables (set OANOCACHE=1)
After a pc reboot, I rested the program but still no positive effect.
In conclusion:
If I do not manipulate BSTR properties, the objects are released correctly but otherwise they seems to cache some memory.
Does somebody have already investigated that effect ?
What could be the ideal solution to avoid that caching effect ?
All kind of information is really welcome.
Thank you very much in advance.
Best regards,
MiQi.