Утечка памяти. sourcemod_fatal.log
|
|
Regedit
|
Дата: Пятница, 28.08.2015, 15:13:09 | Сообщение # 1 |
|
Сообщений: 135
Репутация: 1 [ +/- ]
|
|
Здравствуйте, скажите пожалуйста что как правило приводит к такого рода записям в sourcemod_fatal.log?
Код L 08/27/2015 - 10:16:48: [SM] MEMORY LEAK DETECTED IN PLUGIN (file "my_plugin.smx") L 08/27/2015 - 10:16:48: [SM] Unloading plugin to free 32346 handles. L 08/27/2015 - 10:16:48: [SM] Contact the author(s) of this plugin to correct this error. L 08/27/2015 - 10:16:48: -------------------------------------------------------------------------- L 08/27/2015 - 10:16:48: Type IBaseMenu | Count 32321 L 08/27/2015 - 10:16:48: Type Timer | Count 23 L 08/27/2015 - 10:16:48: Type Regex | Count 2 L 08/27/2015 - 10:16:48: -- Approximately 10826005 bytes of memory are in use by (32346) Handles.
Где можно глянуть все Type утечек памяти и описание?
И небольшой пример:
Код new Handle:HNdl = CreateMenu(Select_Menu); бла... бла..бла.. бла... бла..бла.. бла... бла..бла.. DisplayMenu(HNdl, client, 0);
Нужно ли делать CloseHandle(HNdl); чтоб не было утечки памяти..? или дело не в этом?
Сообщение отредактировал Regedit - Пятница, 28.08.2015, 15:29:14 |
|
| |
Scarface_slv
|
Дата: Пятница, 28.08.2015, 15:42:36 | Сообщение # 2 |
|
Сообщений: 737
Репутация: 61 [ +/- ]
|
|
Цитата Regedit ( ) Нужно ли делать CloseHandle(HNdl); чтоб не было утечки памяти..? или дело не в этом? там нет а вот при нажатие в меню да Код if (action == MenuAction_End) { CloseHandle(menu); }
--------------------------------------------- https://wiki.alliedmods.net/Handle_API_(SourceMod) https://wiki.alliedmods.net/Handles_(SourceMod_Scripting)
Сообщение отредактировал Scarface_slv - Пятница, 28.08.2015, 15:45:21 |
|
| |
Regedit
|
Дата: Суббота, 29.08.2015, 03:27:30 | Сообщение # 3 |
|
Сообщений: 135
Репутация: 1 [ +/- ]
|
|
Цитата Scarface_slv ( ) Цитата Regedit писал(а): Нужно ли делать CloseHandle(HNdl); чтоб не было утечки памяти..? или дело не в этом?
там нет а вот при нажатие в меню да Код
if (action == MenuAction_End) { CloseHandle(menu); }
--------------------------------------------- https://wiki.alliedmods.net/Handle_API_(SourceMod) https://wiki.alliedmods.net/Handles_(SourceMod_Scripting)
ну счет закрытия хэндл когда меня становится не активно я вкурсе, а за литературу спс. )Добавлено (29.08.2015, 03:27:30) --------------------------------------------- После смены карты участки памяти освобождаются?
|
|
| |
_R1KO_
|
Дата: Суббота, 29.08.2015, 10:54:09 | Сообщение # 4 |
|
Сообщений: 200
Репутация: 30 [ +/- ]
|
|
Regedit, нет
|
|
| |
Regedit
|
Дата: Суббота, 29.08.2015, 16:56:37 | Сообщение # 5 |
|
Сообщений: 135
Репутация: 1 [ +/- ]
|
|
Цитата _R1KO_ ( ) Regedit, нет внатуре глупый вопрос))) xD
|
|
| |
pro-health
|
Дата: Воскресенье, 30.08.2015, 17:54:20 | Сообщение # 6 |
|
Сообщений: 188
Репутация: 5 [ +/- ]
|
|
_R1KO_, хм. А ведь менюшки все (если были открыты) закрываются. Или это не закрывает Handle (Очистка памяти)?
|
|
| |
_R1KO_
|
Дата: Воскресенье, 30.08.2015, 20:52:55 | Сообщение # 7 |
|
Сообщений: 200
Репутация: 30 [ +/- ]
|
|
Цитата pro-health ( ) _R1KO_, хм. А ведь менюшки все (если были открыты) закрываются. Или это не закрывает Handle (Очистка памяти)? хандл можешь закрыть только ты или когда плагин выгружается.
|
|
| |
Regedit
|
Дата: Понедельник, 31.08.2015, 12:50:40 | Сообщение # 8 |
|
Сообщений: 135
Репутация: 1 [ +/- ]
|
|
Нужно ли делать HNDL = INVALID_HANDLE; после CloseHandle(HNDL); ??
|
|
| |
Scarface_slv
|
Дата: Понедельник, 31.08.2015, 16:21:49 | Сообщение # 9 |
|
Сообщений: 737
Репутация: 61 [ +/- ]
|
|
Regedit, нет
|
|
| |
_R1KO_
|
Дата: Понедельник, 31.08.2015, 20:11:32 | Сообщение # 10 |
|
Сообщений: 200
Репутация: 30 [ +/- ]
|
|
Цитата Regedit ( ) Нужно ли делать HNDL = INVALID_HANDLE; после CloseHandle(HNDL); ?? Всё зависит от конкретной ситуации. Если ты делаешь CloseHandle и сразу используешь переменную то не нужно, а вот если у тебя будут проверки на HNDL != INVALID_HANDLE тогда нужно т.к. CloseHandle закрывает хандл (очищает память и удаляет указатель) но переменную не очищает, следовательно хандл будет ссылаться на не валидный указатель.
Сообщение отредактировал _R1KO_ - Понедельник, 31.08.2015, 23:10:45 |
|
| |
Regedit
|
Дата: Понедельник, 31.08.2015, 23:45:11 | Сообщение # 11 |
|
Сообщений: 135
Репутация: 1 [ +/- ]
|
|
Цитата _R1KO_ ( ) Цитата Regedit писал(а): Нужно ли делать HNDL = INVALID_HANDLE; после CloseHandle(HNDL); ??
Всё зависит от конкретной ситуации. Если ты делаешь CloseHandle и сразу используешь переменную то не нужно, а вот если у тебя будут проверки на HNDL != INVALID_HANDLE тогда нужно т.к. CloseHandle закрывает хандл (очищает память и удаляет указатель) но переменную не очищает, следовательно хандл будет ссылать на не валидный указатель.
CloseHandle закрывает хандл (очищает память и удаляет указатель) - одним предложением сразу отрезал остальные созревшие вопросы. Спс.Добавлено (31.08.2015, 23:45:11) --------------------------------------------- А в таймере достаточно KillTimer(a_handle); для очистки ячеек памяти?
|
|
| |
_R1KO_
|
Дата: Вторник, 01.09.2015, 00:08:06 | Сообщение # 12 |
|
Сообщений: 200
Репутация: 30 [ +/- ]
|
|
Regedit, таймер это такой же хандл. Только у него своя ф-я закрытия. Цитата Timer Death
All timers are guaranteed to die either by: CloseHandle() being called (or on plugin unload); KillTimer() being called; Plugin_Stop being returned from a repeatable timer; TriggerTimer() being called on a one-time timer; Execution of a one-time timer finishes.
When a timer dies, if TIMER_DATA_HNDL_CLOSE is set, the Handle will always be closed with the permissions that CloseHandle() uses by default. Since timers cannot be cloned, there should be no ownership issues.
|
|
| |
Regedit
|
Дата: Вторник, 01.09.2015, 00:40:53 | Сообщение # 13 |
|
Сообщений: 135
Репутация: 1 [ +/- ]
|
|
Цитата _R1KO_ ( ) Regedit, таймер это такой же хандл. Только у него своя ф-я закрытия.
KillTimer - Достаточно для удаления из памяти, правильно я понял (судя из статьи) ?
|
|
| |
_R1KO_
|
Дата: Вторник, 01.09.2015, 01:12:20 | Сообщение # 14 |
|
Сообщений: 200
Репутация: 30 [ +/- ]
|
|
Regedit, да, это тот же CloseHandle() только для таймера.
Вот их отличия: CloseHandle:
Код static cell_t sm_CloseHandle(IPluginContext *pContext, const cell_t *params) { Handle_t hndl = static_cast<Handle_t>(params[1]); HandleSecurity sec;
sec.pIdentity = NULL; sec.pOwner = pContext->GetIdentity();
HandleError err = handlesys->FreeHandle(hndl, &sec); if (err == HandleError_None) { return 1; } else if (err == HandleError_Access) { return 0; } else { return pContext->ThrowNativeError("Handle %x is invalid (error %d)", hndl, err); } }
KillTimer: Код static cell_t smn_KillTimer(IPluginContext *pCtx, const cell_t *params) { Handle_t hndl = static_cast<Handle_t>(params[1]); HandleError herr; HandleSecurity sec; TimerInfo *pInfo;
sec.pOwner = pCtx->GetIdentity(); sec.pIdentity = g_pCoreIdent;
if ((herr=handlesys->ReadHandle(hndl, g_TimerType, &sec, (void **)&pInfo)) != HandleError_None) { return pCtx->ThrowNativeError("Invalid timer handle %x (error %d)", hndl, herr); }
timersys->KillTimer(pInfo->Timer);
if (params[2] && !(pInfo->Flags & TIMER_DATA_HNDL_CLOSE)) { sec.pOwner = pInfo->pContext->GetIdentity(); sec.pIdentity = g_pCoreIdent;
if ((herr=handlesys->FreeHandle(static_cast<Handle_t>(pInfo->UserData), &sec)) != HandleError_None) { return pCtx->ThrowNativeError("Invalid data handle %x (error %d) on timer kill with TIMER_DATA_HNDL_CLOSE", hndl, herr); } }
return 1; }
Тоесть тот же CloseHandle но удалением хандла, который передается как данные (датапак например)
Сообщение отредактировал _R1KO_ - Вторник, 01.09.2015, 01:16:44 |
|
| |
Regedit
|
Дата: Вторник, 01.09.2015, 06:36:08 | Сообщение # 15 |
|
Сообщений: 135
Репутация: 1 [ +/- ]
|
|
Цитата _R1KO_ ( ) Regedit, да, это тот же CloseHandle() только для таймера.
Вот их отличия: CloseHandle:
Код static cell_t sm_CloseHandle(IPluginContext *pContext, const cell_t *params) { Handle_t hndl = static_cast<Handle_t>(params[1]); HandleSecurity sec;
sec.pIdentity = NULL; sec.pOwner = pContext->GetIdentity();
HandleError err = handlesys->FreeHandle(hndl, &sec);
if (err == HandleError_None) { return 1; } else if (err == HandleError_Access) { return 0; } else { return pContext->ThrowNativeError("Handle %x is invalid (error %d)", hndl, err); } }
KillTimer: Код static cell_t smn_KillTimer(IPluginContext *pCtx, const cell_t *params) { Handle_t hndl = static_cast<Handle_t>(params[1]); HandleError herr; HandleSecurity sec; TimerInfo *pInfo;
sec.pOwner = pCtx->GetIdentity(); sec.pIdentity = g_pCoreIdent;
if ((herr=handlesys->ReadHandle(hndl, g_TimerType, &sec, (void **)&pInfo)) != HandleError_None) { return pCtx->ThrowNativeError("Invalid timer handle %x (error %d)", hndl, herr); }
timersys->KillTimer(pInfo->Timer);
if (params[2] && !(pInfo->Flags & TIMER_DATA_HNDL_CLOSE)) { sec.pOwner = pInfo->pContext->GetIdentity(); sec.pIdentity = g_pCoreIdent;
if ((herr=handlesys->FreeHandle(static_cast<Handle_t>(pInfo->UserData), &sec)) != HandleError_None) { return pCtx->ThrowNativeError("Invalid data handle %x (error %d) on timer kill with TIMER_DATA_HNDL_CLOSE", hndl, herr); } }
return 1; }
Тоесть тот же CloseHandle но удалением хандла, который передается как данные (датапак например)
Круто)) А де ты исходники стандартных функций берешь? (стандартных библиотек <>) ?
Сообщение отредактировал Regedit - Вторник, 01.09.2015, 06:36:36 |
|
| |