Утечка памяти. 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.
1 2 3 4 5 6 7 8
Где можно глянуть все Type утечек памяти и описание?
И небольшой пример:
new Handle:HNdl = CreateMenu(Select_Menu);
бла... бла..бла..
бла... бла..бла..
бла... бла..бла..
DisplayMenu(HNdl, client, 0 );
1 2 3 4 5
Нужно ли делать 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);
}
1 2 3 4
--------------------------------------------- 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, нет
|
|
| | |
pro-health
|
Дата: Воскресенье, 30.08.2015, 17:54:20 | Сообщение # 6 |
|
Сообщений: 188
Репутация: 5 [ +/- ]
|
|
_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.
|
|
| | |
_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);
}
}
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
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 ;
}
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Тоесть тот же 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 |
|
| |
|