在vb6中运行几次后,示例ole自动化服务器dll似乎泄漏了内存 [英] Sample ole automation server dll seems to leak memory after several runs in vb6

查看:69
本文介绍了在vb6中运行几次后,示例ole自动化服务器dll似乎泄漏了内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello Everyone,



我已经基于vs6项目模板创建了一个小型的ole自动化dll服务器程序

''MFC AppWizard (Dll)''



从这个正文项目中,我创建了以下可创建的CCmdTarget对象

CProject

CWorkspaces(添加,删除所有,计数,项目)



CWorkspace

CMeasurements(添加,删除所有,计数,项目)



CMeasurement(名称属性,BSTR类型)



CWorkspaces和CMeasurements仅基于MFC集合CPtrArray来收集IDispatch指针,其中应用了AddRef以避免vb6中的对象破坏。



如果我创建以下vb6代码,我的效果如下:



 私人  Sub  GenerateObject()
Dim lCha nnel 作为
Dim Meas As DummyWsdll.Measurement
Dim SubMeas As DummyWsdll.Measurement
Dim Ws As DummyWsdll.Workspace
< span class =code-comment>' Dim Setup As CSetup
' Dim Inputchannel As CInputChannel

Command1.Enabled = False

设置 Ws = DummyWsdll.Workspace
' Ws.Name =Workspace& CStr(gProject.Workspaces.Count + 1)

对于 lChannel = 1 24

设置 Meas = DummyWsdll.Measurement
Meas.Name = Spectrum(频道& CStr (lChannel)& ,频道& CStr (lChannel)

对于 lBlock = 1 1000
设置 SubMeas = DummyWsdll。测量
SubMeas.Name = Spectrum(频道& CStr (lChannel)& ,Channel& CStr (lChannel)
Meas.Measurements.Add SubMeas
Set SubMeas = < span class =code-keyword> Nothing
Next lBlock
Ws.Measurements.Add Meas
设置 Meas =
下一步 lChannel

gProject.Workspaces.Add Ws
End Sub





在表单加载中,我将全局gProject初始化如下:

 设置 gProject =  DummyWsdll.Project 





在运行vb6程序之前,我查看了任务管理器,内存使用情况为:

35.132Kb



如果我跑几次了GenerateObject例程,我去:

41.332Kb(运行1)

47.000Kb(运行2)

52.772Kb(运行3)



这是效果。如果我运行clean all操作:

 gProject.Workspaces.RemoveAll 





内存使用量返回37.448Kb。

所以我失去了+ - 2Mb这也与我的运行次数有关。



我调查了已实现的对象,我决定从CMeasurement中删除.Name属性



我很惊讶看到内存是什么当我在RemoveAll()之后返回时真的很稳定。



在互联网上,我发现了SetOaNoCache,它显然用于禁用BSTR缓存效果。



当我使用VS6时,我必须按如下方式调用它:

 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);
}
}





我认为这对我有帮助,但这并没有解决我的问题。

我也看到这可以在环境变量中设置(设置OANOCACHE = 1)

重启电脑后,我休息了程序,但仍然没有正面效果。



结论:

如果我不操纵BSTR属性,对象会被正确释放,但是它们似乎会缓存一些内存。



有人已经调查了这种效果吗?

什么可能是避免缓存效果的理想解决方案?



所有类型的信息都非常受欢迎。

非常感谢您提前。

祝你好运,

MiQi。

解决方案

对我来说,你的观察看起来并不像是实际内存泄漏的确凿证据。您不应该相信任务管理器测量内存泄漏。



您需要使用可靠的内存泄漏测量方法。请考虑以下工具列表: http://en.wikipedia.org/wiki/Memory_debugger [ ^ ]。



机会是的,内存调试器将帮助您证明或反驳泄漏的事实,甚至找到真正找到泄漏的原因。


- SA

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
'    Dim Setup As CSetup
'    Dim Inputchannel As CInputChannel
    
    Command1.Enabled = False
    
    Set Ws = New DummyWsdll.Workspace
    'Ws.Name = "Workspace" & CStr(gProject.Workspaces.Count + 1)
    
    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.

解决方案

To me, you observation does not look like a sure evidence of an actual memory leak. You should not trust Task Manager for measuring memory leak.

You need to use a reliable method of memory leak measurements. Please consider this list of tools: http://en.wikipedia.org/wiki/Memory_debugger[^].

Chances are, the memory debugger will help you to prove or disprove the fact of the leak, and even locate the reason if the leak is really found.

—SA


这篇关于在vb6中运行几次后,示例ole自动化服务器dll似乎泄漏了内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆