首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

VC6.0 + SQL Server 2005 ODBC 連接「內存不足」排查實錄

     編輯:程式設計綜合問答

經典 VC6.0 MFC 應用通過 ODBC 連接 SQL Server 2005,運行一段時間後 CRecordset::Open() 拋出「內存不足」異常,且僅能寫入一條記錄。最終通過重建數據庫解決,但根因未定論。本文復盤排查路徑,提供可復用的自查清單。

現象複現

  • 環境:VC6.0 SP6 + WinXP/Win7 + SQL Server 2005 SP4 + SQL Native Client ODBC 驅動。
  • 代碼片段:
CRecordSet m_useBLOB; // 派生自 CRecordset
try {
    m_useBLOB.Open(); // 斷點處直接跳 catch
    // ...
} catch (CException* pE) {
    pE->ReportError(); // 提示「內存不足」
    pE->Delete();
}
  • 規律:首次寫入成功,第二次即報錯;重啟應用暫時恢復。

排查清單(按命中率排序)

疑點驗證方法典型徵兆
ODBC 驅動/客戶端內存洩漏換用 SQL Server Native Client 10.0 或更高版驅動;啟用 ODBC 追蹤日志驅動版本舊(2005 早期版)、長連接不斷增長
CRecordset 未正確關閉檢查所有分支是否調用 Close();析構函數中兜底關閉異常拋出路徑漏調 Close、事務未提交/回滾
BLOB/CLOB 字段處理不當改用 CLongBinary 或 CLongBinary::GetData() 分塊讀寫表含 image/text/ntext 類型、單條數據 > 1MB
連接池/會話泄漏ODBC 管理器查看活動連接數;代碼確保 CDatabase::Close() 配對連接數隨時間單調遞增、達到最大連接數
SQL Server 內存配置/碎片SSMS 查看 target server memory、DBCC MEMORYSTATUS;重建數據庫/重建索引重建數據庫後症狀消失(本案實測有效)
VC6 運行時庫/堆損壞改用 /MD 動態鏈接 CRT;啟用 _CrtSetDbgFlag 檢測堆完整性Debug 模式下斷點觸發 _CrtIsValidHeapPointer 失敗

本案實測有效動作

  1. 備份數據 → 刪除庫 → 重建庫 → 還原數據 → 症狀消失。
  2. 安裝 SQL Server 2005 SP4 + 累積更新包(CU)未單獨解決,但構成基線。

長期建議

  • 遷移至 VS2019+ / SQL Server 2019+:VC6/SQL2005 均已終止支持,安全風險極高。
  • 引入連接池中間層:如 OLE DB Services 或自建連接池,隔離 ODBC 狀態。
  • 加入健康檢查:定時執行 SELECT 1 探活,失敗時重建連接對象。

若仍需維護舊系統,建議在啟動時強制設置 SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1) 釋放工作集,緩解虛擬地址空間碎片(32 位進程 2GB 限制下常見緩解手段)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved