为什么登录到Oracle会泄漏内存?
我正在写一个服务发送短信。为此,将定期启动一个单独的线程。我连接到SQL server,获取新消息,将它们发送到Oracle SMS server数据库进行进一步处理,然后断开与这两个数据库的连接。我的问题是,如果我连接到Oracle然后断开连接,总内存消耗会随着时间的推移而增加(不是每次启动)。如果我省略这一步(登录到Oracle),一切都正常。除了连接和断开之外,我已经注释掉了所有内容。我使用Oracle客户端19c。 代码如下:为什么登录到Oracle会泄漏内存?,c,oracle,winapi,C,Oracle,Winapi,我正在写一个服务发送短信。为此,将定期启动一个单独的线程。我连接到SQL server,获取新消息,将它们发送到Oracle SMS server数据库进行进一步处理,然后断开与这两个数据库的连接。我的问题是,如果我连接到Oracle然后断开连接,总内存消耗会随着时间的推移而增加(不是每次启动)。如果我省略这一步(登录到Oracle),一切都正常。除了连接和断开之外,我已经注释掉了所有内容。我使用Oracle客户端19c。 代码如下: DWORD Timer(LPVOID lpParam
DWORD Timer(LPVOID lpParameter){
DWORD SMSTaskResult = 0;
HANDLE SMSTaskThread;
while (1)
{
//WriteLog(LOG_RECORD_TYPE_INFO, 1, "Running task");
SMSTaskThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) &RunSMSTask,0,0,0);
if (SMSTaskThread == NULL) {
WriteLog(LOG_RECORD_TYPE_ERROR, 1, "Unable to run SMS Task. Error creating thread"); SvcStopSuccess = false; SetEvent(SvcStopEvent); return 1;
}
else {
WaitForSingleObject(SMSTaskThread, INFINITE);
if (!GetExitCodeThread(SMSTaskThread, &SMSTaskResult)) {
WriteLog(LOG_RECORD_TYPE_ERROR, 1, "Unable to get task result. Exiting"); CloseHandle(SMSTaskThread); SvcStopSuccess = false;
SetEvent(SvcStopEvent);return 1;
}
CloseHandle(SMSTaskThread);
if (SMSTaskResult != 0) { WriteLog(LOG_RECORD_TYPE_ERROR, 1, "Critical error. Stopping timer"); SvcStopSuccess = false; SetEvent(SvcStopEvent); return 1; }
}
Sleep(run_interval);
}
return 0;}
DWORD RunSMSTask(LPVOID LpParameter){
int ExitCode = 0; if (TaskRunning) return 0;
hOCISvc = NULL;
TaskRunning = true;
WriteLog(LOG_RECORD_TYPE_INFO, 1, "Running task");
RetCode = SQLDriverConnect(hDbc, NULL, (SQLCHAR*)atlant, SQL_NTS, NULL,0, NULL, SQL_DRIVER_NOPROMPT);
if (RetCode != SQL_SUCCESS) { HandleDiagnosticRecord2(hDbc, SQL_HANDLE_DBC, RetCode,NULL); if (RetCode != SQL_SUCCESS_WITH_INFO) {ExitCode = -1; goto Exit;}}
OCIRetCode = OCILogon2(hOCIEnv, hOCIError, &hOCISvc, (text*)oracle_user, strlen(oracle_user), (text*)oracle_password, strlen(oracle_password), (text*)oracle_host, strlen(oracle_host),OCI_DEFAULT);
if (OCIRetCode != OCI_SUCCESS) {
HandleOracleError2(hOCIError, OCI_HTYPE_ERROR, OCIRetCode, NULL); if (OCIRetCode != OCI_SUCCESS_WITH_INFO) goto Exit;
}
Exit:
if (hOCISvc) { OCIRetCode = OCILogoff(hOCISvc, hOCIError); if (OCIRetCode != OCI_SUCCESS) {
HandleOracleError2(hOCIError, OCI_HTYPE_ERROR, OCIRetCode, NULL); if (OCIRetCode != OCI_SUCCESS_WITH_INFO) goto Exit;
}
}
if (hDbc)
{
RetCode = SQLDisconnect(hDbc);
if (RetCode != SQL_SUCCESS) {
HandleDiagnosticRecord2(hDbc, SQL_HANDLE_DBC, RetCode, NULL);
}
}
TaskRunning = false;
return ExitCode;
}
你是如何得到你的
hDbc
,你在上面被称为sqlfreehold()
?创建RunSMSTask
线程而不是仅仅等待它有什么意义?为什么不直接调用RunSMSTask
?您是否已验证这是真正的资源泄漏?缓存实现可以表现出与资源泄漏相同的可观察内存消耗模式。如果我需要一次发送多条消息,则可以使用单独的线程。我不确定我是否需要它。我按照这种模式做了其他工作(自动拨号、邮件发送者等)。该服务最初使用的内存不足6兆字节。现在,一天之后,它有7,6-7,8兆的ram,跳跃和下降,但大致在同一水平上。奇怪的是,在使用SQL odbc连接的情况下,我没有看到内存使用量有如此大的增加,但使用OCI时,它大约有2 MB的RAM。它看起来像是缓存了一些东西。如果我将此服务与那些用C#编写的服务进行比较,消耗的RAM量会减少几倍,但与常规服务相比仍然太多。您如何获得hDbc
,您是否被称为sqlfreehold()
在它上面?创建运行SMSTASK
线程,而不仅仅是等待它有什么意义?为什么不直接调用RunSMSTask
?您是否已验证这是真正的资源泄漏?缓存实现可以表现出与资源泄漏相同的可观察内存消耗模式。如果我需要一次发送多条消息,则可以使用单独的线程。我不确定我是否需要它。我按照这种模式做了其他工作(自动拨号、邮件发送者等)。该服务最初使用的内存不足6兆字节。现在,一天之后,它有7,6-7,8兆的ram,跳跃和下降,但大致在同一水平上。奇怪的是,在使用SQL odbc连接的情况下,我没有看到内存使用量有如此大的增加,但使用OCI时,它大约有2 MB的RAM。它看起来像是缓存了一些东西。如果我将此服务与那些用C#编写的服务进行比较,所消耗的RAM量会减少几倍,但与常规服务相比仍然太多。