|
|
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Господа, прошу руку помощи. Уже просто замучался. Проблема в следующем: нужно из базы сделать выборку (из двух таблиц), В принципе все работает, НО после выполнения pICommandText->Execute исчезает примерно около полумегабайта памяти. Таблица Clients занимает тоже около того, а DocNum - в принципе маленькая (строк 15 пока). Т.е. по идее результат запроса должен занимать несколько килобайт. Так вот даже после выполнения всех Release() память не возвращается :( Помогите решить проблему. Куда девается память? Вот код: ... wsprintf(sqlQuery, L"SELECT DocNum, Name FROM Clients AS Cl, DocHeads AS DH WHERE DH.ClientID = Cl.ExternalID"); pICommandText->SetCommandText(DBGUID_DBSQL, sqlQuery); pICommandText->Execute(NULL, IID_IRowset, NULL, NULL, (IUnknown**) &pIRowset); сразу после этого оператора уходит ~500 Kb памяти, даже если таблица DocNum совсем пустая (т.е. результат должен быть нулевой ...) ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.11.2003, 21:09 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
В каком программном продукте работаете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2003, 12:55 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Visual C++ правда под КПК, но я думаю, особо разницы нет... Насколько я понял, там SQL Server забирает всю доступную память, пока не съест все целиком, а потом просто прога вылетает при очередном запросе. И если я правильно понимаю суть, надо ограничить память доступную для SQL Server'a... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2003, 14:02 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
grifon писал:И если я правильно понимаю суть, надо ограничить память доступную для SQL Server'a... В SQL Enterprise Manager свойства сервера(если у тебя есть права админа) закладка Memory Поставь крыжик вместо Dynamically configure SQL Server memory на Use a fixed memory size или там же можешь просто задать макимальный размер а вообще то укажи для коннектора (который к серваку подключается)pICommandText m_ptrConnection->CursorLocation = adUseServer; или adUseClient посмотри гда меньше жрать будет ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.11.2003, 14:46 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Возможно это слегка не в тему, но правильнее объединять таблицы JOIN'ом, а не WHERE: SELECT DocNum, Name FROM Clients AS Cl INNER JOIN DocHeads AS DH ON DH.ClientID = Cl.ExternalID Более того, лучше написать DocHeads AS DH INNER JOIN Clients AS Cl ON Cl.ExternalID = DH.ClientID, т.е. начать с маленькой таблицы. Не исключено, что тогда и SQL Server догадается, что нужна не вся таблица Clients. Clients.ExternalID, DocHeads.ClientID -- уникальные индексы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2003, 13:01 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Хорошо бы увидеть код после Execute... Может в цикле не вызывается ReleaseRows??? Какой используется аксессор? Кто в нем владеет памятью? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2003, 14:10 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Ой Вэй писал:Возможно это слегка не в тему, но правильнее объединять таблицы JOIN'ом, а не WHERE Спасибо за совет. _Konst писал:Хорошо бы увидеть код после Execute... Решил привести код по открытию БД ( OpenDatabase ) и при выполнении запроса GetAllStocks(HWND g_hDlg) HRESULT Mains::OpenDatabase() { HRESULT hr = NOERROR; DBPROP dbprop[1]; DBPROPSET dbpropset[1]; IDBInitialize *pIDBInitialize = NULL; IDBProperties *pIDBProperties = NULL; VariantInit(&dbprop[0].vValue); hr = CoCreateInstance( CLSID_SQLSERVERCE_2_0, 0, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&pIDBInitialize); if(FAILED(hr)) { goto Exit; } dbprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE; dbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED; dbprop[0].vValue.vt = VT_BSTR; dbprop[0].vValue.bstrVal= SysAllocString(DATABASE_PRESALE); if(NULL == dbprop[0].vValue.bstrVal) { hr = E_OUTOFMEMORY; goto Exit; } dbpropset[0].guidPropertySet = DBPROPSET_DBINIT; dbpropset[0].rgProperties = dbprop; dbpropset[0].cProperties = sizeof(dbprop)/sizeof(dbprop[0]); hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void **)&pIDBProperties); if(FAILED(hr)) { goto Exit; } hr = pIDBProperties->SetProperties(1, dbpropset); if(FAILED(hr)) { goto Exit; } hr = pIDBInitialize->Initialize(); if(FAILED(hr)) { goto Exit; } hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession, (void**)&m_pIDBCreateSession); Exit: VariantClear(&dbprop[0].vValue); if(pIDBProperties) { pIDBProperties->Release(); } if (pIDBInitialize) { pIDBInitialize->Release(); } return hr; } HRESULT Mains::GetAllStocks(HWND g_hDlg) { HRESULT hr = NOERROR; DBBINDING *pDBBindings; DBBINDSTATUS *pDBBindStatus = NULL; ULONG cbRow = 0; IDBCreateCommand*pIDBCreateCommand = NULL; ICommandText *pICommandText = NULL; IAccessor *pIAccessor = NULL; IOpenRowset *pIOpenRowset = NULL; IRowset *pIRowset = NULL; HACCESSOR hAccessor = DB_NULL_HACCESSOR; IColumnsInfo *pIColumnsInfo; ULONG nCols; DBCOLUMNINFO *pColumnsInfo = NULL; OLECHAR *pColumnStrings = NULL; ULONG cRowsObtained; HROW rghRows[1]; HROW * pRows = rghRows; char * pRowValues; LPWSTR sqlQuery = NULL; WCHAR *pwszName = NULL; LVITEM lvTest; UINT iIndex = 0; HWND hListViewCtrl; ULONG nCol; if (NULL == m_pIDBCreateSession) { hr = E_POINTER; goto Exit; } hr = m_pIDBCreateSession->CreateSession(NULL, IID_IDBCreateCommand, (IUnknown**) &pIDBCreateCommand); if (FAILED(hr)) { goto Exit; } hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**) &pICommandText); if (FAILED(hr)) { goto Exit; } sqlQuery = (LPWSTR)CoTaskMemAlloc(200); wsprintf(sqlQuery, L"SELECT DocNum, Name FROM DocHeads AS DH INNER JOIN Clients AS Cl ON Cl.ExternalID = DH.ClientID"); hr = pICommandText->SetCommandText(DBGUID_DBSQL, sqlQuery); if (FAILED(hr)) { goto Exit; } hr = pICommandText->Execute(NULL, IID_IRowset, NULL, NULL, (IUnknown**) &pIRowset); if(FAILED(hr)) { goto Exit; } hr=pIRowset->QueryInterface(IID_IColumnsInfo, (void**)&pIColumnsInfo); if (FAILED(hr)) { goto Exit; } hr = pIColumnsInfo->GetColumnInfo(&nCols, &pColumnsInfo,&pColumnStrings); if (FAILED(hr)) { goto Exit; } pDBBindings = new DBBINDING[nCols]; for (nCol = 0; nCol < nCols; nCol++) { pDBBindings[nCol].iOrdinal = nCol+1; pDBBindings[nCol].obValue = cbRow; pDBBindings[nCol].obLength = 0; pDBBindings[nCol].obStatus = 0; pDBBindings[nCol].pTypeInfo = NULL; pDBBindings[nCol].pObject = NULL; pDBBindings[nCol].pBindExt = NULL; pDBBindings[nCol].dwPart = DBPART_VALUE; pDBBindings[nCol].dwMemOwner = DBMEMOWNER_CLIENTOWNED; pDBBindings[nCol].eParamIO = DBPARAMIO_NOTPARAM; pDBBindings[nCol].cbMaxLen = 2*(pColumnsInfo[nCol].ulColumnSize + 1); pDBBindings[nCol].dwFlags = 0; pDBBindings[nCol].wType = pColumnsInfo[nCol].wType; pDBBindings[nCol].bPrecision = pColumnsInfo[nCol].bPrecision; pDBBindings[nCol].bScale = pColumnsInfo[nCol].bScale; cbRow += pDBBindings[nCol].cbMaxLen; } pDBBindStatus = new DBBINDSTATUS[nCols]; hr=pIRowset->QueryInterface(IID_IAccessor, (void**) &pIAccessor); if (FAILED(hr)) { goto Exit; } hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,nCols, pDBBindings,0,&hAccessor,pDBBindStatus); if (FAILED(hr)) { goto Exit; } pRowValues = new char[cbRow]; hListViewCtrl = GetDlgItem(g_hDlg, IDC_STOCKSLIST); ListView_DeleteAllItems(hListViewCtrl); pwszName = (WCHAR*)CoTaskMemAlloc(pDBBindings[0].cbMaxLen + pDBBindings[1].cbMaxLen + 2); CurrentStockID = 1; hr = pIRowset->GetNextRows(DB_NULL_HCHAPTER,0,1,&cRowsObtained,&pRows ); while (SUCCEEDED(hr) && DB_S_ENDOFROWSET != hr) { pIRowset->GetData(pRows[0], hAccessor, pRowValues); wsprintf(pwszName, L"%d", *(int*)(pRowValues+pDBBindings[0].obValue)); lvTest.mask = LVIF_TEXT | LVIF_STATE; lvTest.iItem = 0; lvTest.pszText = pwszName; lvTest.iIndent = 0; lvTest.stateMask = 0; lvTest.state = 0; lvTest.iSubItem = 0; iIndex = ListView_InsertItem(hListViewCtrl, &lvTest); wcscpy(pwszName, (WCHAR*)(pRowValues+pDBBindings[1].obValue)); ListView_SetItemText( hListViewCtrl,iIndex,2,pwszName); CurrentStockID++; hr = pIRowset->ReleaseRows(1, pRows, NULL, NULL, NULL); if(FAILED(hr)) { goto Exit; } hr = pIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &pRows); } Exit: if (pRows) { CoTaskMemFree(pRows); pRows = NULL; } if (pwszName) { CoTaskMemFree(pwszName); pwszName = NULL; } if (sqlQuery) { CoTaskMemFree(sqlQuery); sqlQuery = NULL; } if(pDBBindings) { delete [] pDBBindings; } if(pDBBindStatus) { delete [] pDBBindStatus; } if(pIAccessor) { pIAccessor->ReleaseAccessor(hAccessor, NULL); pIAccessor->Release(); } if(pRowValues) { delete [] pRowValues; } if(pIColumnsInfo) { pIColumnsInfo->Release(); } if(pIRowset) { pIRowset->Release(); } if(pICommandText) { pICommandText->Release(); } if(pIDBCreateCommand) { pIDBCreateCommand->Release(); } return hr; } ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2003, 16:22 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Меня сейчас больше волнует проблема при использовании позиционирования в таблице. Суть проблемы: есть ListView, в котором отображается набор записей, полученных с помощью запроса. В ListView выбирается строка, а в соответствующих Edit'ах должна отображаться информация из полей таблицы. Для этого делаю Seek. Но постоянно вылетает: "First-chance exception in presale.exe: 0xC0000005: Access Violation" . и в режиме отладки прога вылетает в ассемблерный код. Ошибка появляется чаще всего после нескольких вызовов функции, в которой и осуществляется позиционирование. Попытаюсь привести код функции, в которой происходит ошибка: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. Насколько я смог определить, ошибка происходит в последнем Release, т.е. при попытке выполнить: pIRowsetIndex->Release(); По крайней мере при пошаговом выполнении при попытке выполнить его, вылетает Access Violation Из FindGoodInObjects вызывается следующая функция: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2003, 16:49 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
По поводу Access Violation, если глаза вас не обманули и программа действительно падает на Release, все объясняется очень просто - этот Release лишний - предыдущий вызов Release убил объект и все его интерфейсы указывают далее в никуда. Про отъедание памяти ничего не скажу - не нашел :(, хотя это не значит, что этого не происходит. Чего бы вам не воспользоваться NuMega Bounds Checker-ом? Ну или не вставить все это в обычный Visual с директивой Код: plaintext 1. 2. 3. 4. он и покажет, если чего не освобождаете. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.12.2003, 17:49 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
_Konst писал:По поводу Access Violation, если глаза вас не обманули и программа действительно падает на Release, все объясняется очень просто - этот Release лишний - предыдущий вызов Release убил объект и все его интерфейсы указывают далее в никуда. Все дело в том, что Access Violation вылетает не каждый раз :( Функция может отработать 10-15-20 раз и все будет нормально, а может рухнуть после первой же попытке... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2003, 00:49 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
А это ни о чем не говорит. Стандарт OLE не обязывает кокласс удалять себя немедленно по достижении счетчиком сылок нуля. В некоторых случаях бывает даже полезно заблокировать кокласс в памяти (фабрике классов для этого сделали ф-ию LockServer). Попробуйте перед последним Release-ом вызвать ф-ию CoFreeUnusedLibraries - возможно это "стабилизирует" ситуацию ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2003, 15:46 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Спасибо за ваши советы... Но, к сожалению ничего так и не помогло... По поводу Access Violation: после долгих мучений смог откопать такую вещь: после того как закоментировал строки с использованием динамических переменных ошибок больше не наблюдалось. На мой взгляд использование верное, поэтому прошу вашей помощи. То, что закоментировано, указано дополнительно. После закоментированных строк написаны аналоги, только без применения динамических переменных. Помогите разобраться, не могу понять в чем дело. Судя по всему, работа с базой здесь совсем не причем... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2003, 15:29 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Пока нет времени детально вникнуть в ваш код. Но одно можно сказать точно - правильное динамическое выделение памяти (если оно правильное) здесь ни при чем. Я это утверждаю не потому, что просто верю SQL Server-у. Сам пользуюсь классом (своим же) для чтения произвольной таблицы произвольного провайдера (в частности SQL Server) в текстовом виде. Понятно, что биндинги у меня динамические, правда, память под даннные я выделяю по new, а не CoTaskMemAlloc-ом. Все работает! Мне правда, почему-то не удается открыть индекс... а очень хочется, приходится по тупому позиционироваться на запись. А под эти КПК нельзя использовать ATL? Там все, что вам нужно займет от силы строчек 20... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2003, 18:41 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
Спасибо за помощь и поддержку. Решение оказалось как всегда на поверхности. Похоже я памяти мало выделял под переменные. Выделил побольше и все заработало. Ух. Спасибо огромное за помощь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2003, 21:36 |
|
||
|
Проблемы с памятью при работе с базой данных
|
|||
|---|---|---|---|
|
#18+
_KonstА под эти КПК нельзя использовать ATL? Там все, что вам нужно займет от силы строчек 20... Похоже что есть, но уже поздно пить боржоми :) Надо было раньше думать. Тут до конца проекта осталось не так много... Ещё раз спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2003, 22:12 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=32342199&tid=2035704]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
89ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
| others: | 248ms |
| total: | 436ms |

| 0 / 0 |
