对ADO的疑问!

petewong 2010-10-29 03:55:36
一直怀疑ADO对内存管理是不是有问题!
先上测试代码,然后说问题吧!

//全局
_RecordsetPtr g_Rs;
_ConnectionPtr g_Conn;

CADOTest::CADOTest()
{
AfxOleInit();

g_Rs = NULL;
try
{
g_Conn.CreateInstance(__uuidof(Connection));
g_Conn->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=ADOTest.mdb; Persist Security Info=TRUE;","","",adModeUnknown);
}
catch(_com_error e)
{
AfxMessageBox(e.ErrorMessage());
}
}

CADOTest::~CADOTest()
{
if (NULL != g_Rs)
{
if(adStateClosed != g_Rs->State)
g_Rs->Close();
g_Rs = NULL;
}

if (NULL != g_Conn)
{
if (adStateClosed != g_Conn->State)
g_Conn->Close();
g_Conn = NULL;
}
}

void CADOTest::InsertData()
{
if(NULL != g_Conn && adStateOpen == g_Conn->State)
{
g_Rs.CreateInstance(__uuidof(Recordset));
_variant_t strSQL;
strSQL.SetString("SELECT TOP 1 * FROM ADOTable");
g_Rs->Open(strSQL,
g_Conn.GetInterfacePtr(),
adOpenDynamic,
adLockOptimistic,
adCmdText);

for(int i = 1;i <= 1000;i++)
{
g_Rs->AddNew();
_variant_t var;
var.SetString("Data");
g_Rs->PutCollect(long(0),&var);
g_Rs->Update();
}

g_Rs.Close();
g_Rs = NULL;
}
}




问题在于每执行一次 InsertData(),内存就涨,然后就不下来了。
不知道哪里有问题。所以只能怀疑ADO将数据放入缓存中,没有释放。
哪位知道问题在哪,多谢赐教!
另外,代码不长,对迎测试!
...全文
168 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
petewong 2010-11-08
  • 打赏
  • 举报
回复
算了 结帖吧
petewong 2010-11-05
  • 打赏
  • 举报
回复
大家如果感兴趣 可以直接copy上面的代码试 一试就知
sd6814466 2010-11-05
  • 打赏
  • 举报
回复
嘿嘿,我也注意到过这个问题,写入*.mdb文件内存会持续增长,由4M增长为24M左右会停止增长,原因也是添加数据。
涉及数据库不深,只是简单用用,个人估计内存增长原因是随着记录条数的增加,记录集会增大,也就会增加占用的内存,而记录集大小应该是有限制的,所以增长到一定内存就不再增加了。
如果是用command而不是用recordset,也许能解决内存增长的问题,因为command并不返回记录集。
不过SQL语言没学过,尝试用command语言总是出错,程序崩溃,最后人崩溃,不想搞了,就暂时放弃了,让他增长去吧,顶多也就24M,不碍事,等我搞懂了SQL再说。。。
shiter 2010-11-05
  • 打赏
  • 举报
回复
sql2000..没问题。。
康斯坦汀 2010-11-02
  • 打赏
  • 举报
回复
建议用下面这个封装好的ADO类 http://www.codeproject.com/KB/database/caaadoclass1.aspx
LuciferStar 2010-11-02
  • 打赏
  • 举报
回复
不好意思,我的应用中是用的VARIANT 。通过VariantClear解决了内存泄露问题。

[Quote=引用 10 楼 petewong 的回复:]
引用 7 楼 luciferstar 的回复:
C++ Language Reference
_variant_t::Clear
See Also
Collapse All Expand All Language Filter: All Language Filter: Multiple Language Filter: Visual Basic Language Filter: C# L……
[/Quote]
shakaqrj 2010-11-02
  • 打赏
  • 举报
回复
没注意过
不如先去掉那些操作,直接打开关闭,看看是否存在内存泄漏
LuciferStar 2010-11-02
  • 打赏
  • 举报
回复
这个应该不是缓存问题。缓存的话,是mssql的进程占用大量内存,现在是这个应用程序。
erhan_106 2010-11-02
  • 打赏
  • 举报
回复
你说的这种内存增长的问题我以前也遇到过,不过我当时用的是SQL2000数据库,因为如果你不对SQL2000数据库引擎设置它的最大占用内存数的话,它会自动将你查询过的记录都保存到缓存中,用来优化查询速率,使得以后的查询命中率提高,尽管程序中对查询的记录集关闭释放都不起作用,必须在SQL2000数据库中进行内存上限的设置。
但我不知道ACESS数据库是不是也是这样的,另外我觉得虚拟内存本来就是动态变化的,你应该确定一下内存是不是在一定时间之后只增不降。
petewong 2010-11-01
  • 打赏
  • 举报
回复
关于_variant_t,再贴出 其Clear()函数

// Clear the _variant_t
//
inline void _variant_t::Clear()
{
_com_util::CheckError(::VariantClear(this));
}


可以看出 _variant_t 析构时 与Clear函数 都是调用::VariantClear(this)
所以 不是_variant_t的问题

petewong 2010-11-01
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 luciferstar 的回复:]
C++ Language Reference
_variant_t::Clear
See Also
Collapse All Expand All Language Filter: All Language Filter: Multiple Language Filter: Visual Basic Language Filter: C# Language Filter: C+……
[/Quote]

关于_variant_t 是对VARIANT的封装,它会管理VARIANT相关资源,以下是_variant_t析构时的定义:

//////////////////////////////////////////////////////////////////////////////////////////
//
// Destructor
//
//////////////////////////////////////////////////////////////////////////////////////////

inline _variant_t::~_variant_t() throw()
{
::VariantClear(this);
}



csdn的高手们哪去了?
BIN307 2010-10-31
  • 打赏
  • 举报
回复
学习中
LuciferStar 2010-10-30
  • 打赏
  • 举报
回复
VARIANT vtProp;
VariantInit(&vtProp);
...
VariantClear(&vtProp);
LuciferStar 2010-10-30
  • 打赏
  • 举报
回复
C++ Language Reference
_variant_t::Clear
See Also
Collapse All Expand All Language Filter: All Language Filter: Multiple Language Filter: Visual Basic Language Filter: C# Language Filter: C++ Language Filter: J# Language Filter: JScript
Visual Basic (Declaration)
Visual Basic (Usage)
C#
C++
J#
JScript

Microsoft Specific

Clears the encapsulated VARIANT object.


void Clear( );


Remarks
Calls VariantClear on the encapsulated VARIANT object.

END Microsoft Specific
petewong 2010-10-30
  • 打赏
  • 举报
回复
没有人有答案吗?
难道你们的程序都不存在这个问题?
petewong 2010-10-29
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 saiyaman5 的回复:]
g_Conn = NULL;
g_Rs = NULL;

之前先
g_Conn.Release;
g_Rs.Release;

最好是把
g_Conn 和 g_Rs 定义为CADOTest的成员变量.
[/Quote]

大哥,你测过吗
_RecordsetPtr这个智能指针重载了=操作符,=NULL是会自已调用Release;
如果自行先调用Release,再=NULL,等于调用了两次Release,不只是多于,而且在新版本中,会报错的。
Connect对像一样。

至于是不是成员对象,这个只是个测试程序,只考虑方便就行。
petewong 2010-10-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 feilongjilei 的回复:]
C/C++ code

for(int i = 1;i <= 1000;i++)
{
g_Rs->AddNew();
_variant_t var;
var.SetString("Data");
g_Rs->PutCollect(long(0),&var);
……
[/Quote]

对是g_Rs->Close();
手打代码,非复制,有误

另外,我不想关闭数据库,一直处于连接状态。

saiyaman5 2010-10-29
  • 打赏
  • 举报
回复
g_Conn = NULL;
g_Rs = NULL;

之前先
g_Conn.Release;
g_Rs.Release;

最好是把
g_Conn 和 g_Rs 定义为CADOTest的成员变量.
feilongjilei 2010-10-29
  • 打赏
  • 举报
回复

for(int i = 1;i <= 1000;i++)
{
g_Rs->AddNew();
_variant_t var;
var.SetString("Data");
g_Rs->PutCollect(long(0),&var);
g_Rs->Update();
}

g_Rs.Close();
g_Rs = NULL;


应该是g_Rs->Close()吧!
petewong 2010-10-29
  • 打赏
  • 举报
回复
还有 我的MDAC版本是2.81.1132.0

4,011

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧