Anonymous | Login | Signup for a new account | 21-11-24 13:20 UTC |
All Projects | SAS.Планета | Домен, сайт, форум, багтрекер | Доработка карты (ZMP) | Переводы и локализации | Прочее |
My View | View Issues | Change Log | Roadmap | Search |
View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
0001220 | SAS.Планета | [All Projects] Баг | public | 15-03-2012 16:51 | 10-10-2012 11:47 | ||||
Reporter | vasketsov | ||||||||
Assigned To | vdemidov | ||||||||
Priority | normal | Severity | major | Reproducibility | sometimes | ||||
Status | closed | Resolution | fixed | ||||||
Platform | Windows | OS | Vista | OS Version | Ultimate | ||||
Product Version | .Nightly | ||||||||
Target Version | 120808 | Fixed in Version | 120808 | ||||||
Summary | 0001220: При длительном безостановочном перемещении карты возникает EOutOfMemory (не утечка) | ||||||||
Description | Это описание как отловить и защититься. На примере u_MapType.pas. 1. Создаём функцию function CatchedOutOfMemory(const AException: Exception): Boolean; begin Result := Assigned(AException) and ((AException is EOutOfMemory) or (System.Pos('out of memory', LowerCase(AException.Message))>0)); end; 2. Внутри TMapType.LoadTileFromPreZ ищем spr.SetSize и заменяем его на: try spr.SetSize(VTileTargetBounds.Right, VTileTargetBounds.Bottom); except on E: Exception do begin if CatchedOutOfMemory(E) then begin // cleanup if Assigned(FCacheBitmap) then FCacheBitmap.Clear; if Assigned(FCacheVector) then FCacheVector.Clear; // repeat spr.SetSize(VTileTargetBounds.Right, VTileTargetBounds.Bottom); end else begin raise; end; end; end; Теперь если память заюзана под завязку (скажем, все 3 гига), данный кусок отловит исключение из битмапки, подчистит и не даст мгновенно умереть. Если после этого ничего не двигать и ещё подождать, то сработает сборщик мусора и соберёт вообще всё что нагуляли. То есть это не утечка. Итого - надо научиться звать сборщик мусора, чтобы он не доводил до того, что памяти больше нету. Даже если обсуживаемая им сущность вовсю юзается, при достижении определённой границы оставшейся доступной памяти он должен исполнять контрольный TTL в голову всем, кто не спрятался. Ну или как-то более фигурно. Покуда в моём примере ТОЛЬКО перемещается карта - соответственно скорее всего речь идёт о подчистке кэша в памяти. НО править именно кэш в памяти очевидно некорректно. Сам по себе кэш в памяти ничего не знает про друге кэши и про других пожирателей памяти. Так что необходимо общее решение. | ||||||||
Steps To Reproduce | 1. Открываем сас и для наглядности поверх него таскманагер на закладке с пмятью. 2. Сасу вписываем число кэшируемых тайлов несколько тыщ. На самом деле не так уж и много, у мну 3000. 3. Начинаем яростно елозить картой вправо-влево - наблюдаем рост сожранной памяти. В зависимости от скорости работы и количества памяти очевидно тангенс угла наклона линии может быть разный. Не останавливаемся. Может быть минут 10. 4. Когда память кончается - получаем в лицо EOutOfMemory внутри битмапки, наружу исключение вылетает уже текстом, но не суть. Возможно исключение кинется в другом месте. Значит не повезло. 5. После продолжения работы ждём и смотрил глазами в таскманагер. Как придёт мусорщик - сразу использованная память грохнется вниз до первоначальных значений. | ||||||||
Tags | No tags attached. | ||||||||
Attached Files | |||||||||
Notes | |
(0006119) Garl (manager) 15-03-2012 17:23 |
гето в недрах u_MapType.pas у меня тоже вылетает при генерации вышележащих слоёв и движении картой. только количество кэшируемых тайлов у меня всегда 0 |
(0006120) vasketsov (manager) 15-03-2012 17:32 |
Серьёзность баги обусловлена ещё и тем, что при езде в машине с GPS-ом карта _постоянно_ перемещается безо всяких мышек и таскманагеров. Соответственно падение традиционно будет происходить в самый ответственный момент. >в недрах u_MapType.pas Там в старой ревизии было 2 традиционных места, так как при указанных операциях 99% что свалится на выделении памяти под битмапку - соответственно это либо SetSize либо LoadFromStream. |
(0006121) Garl (manager) 15-03-2012 17:45 |
>Там в старой ревизии было 2 традиционных места, в ночнушке уже поправлено. утром можно тестить? |
(0006122) vasketsov (manager) 15-03-2012 17:51 |
>в ночнушке уже поправлено Ни в коем случае. Ловить нехватку памяти в одном конкретном месте очевидно моветон. Я просто пример привёл, как воспроизвести, отловить и придушить. Кроме того LoadFromStream переписан by vdemidov. Так что где вместо этого будет прилетать - ещё не знаю. Вощем надо думать как красиво это порешить. |
(0006133) vdemidov (manager) 15-03-2012 22:08 |
Ты садюга. 3000 битмап тайлов это 756 мегабайт. И это только на одину карту или активный слой. И только кэша. Да еще и каша на базе стринглиста. Тобишь Карта+слой+слой с гарантией съедают все доступные 2 гига доступные для процесса. |
(0006136) vasketsov (manager) 15-03-2012 22:17 |
У мну опция стоит в бут.ини, мне 3 гига доступны для процесса. Но сути это не меняет. Сделай 1000, включи 5 слоёв - и получишь то же самое. |
(0006137) vdemidov (manager) 15-03-2012 22:22 |
3 гига доступны для процессов, которые скомпилены с поддержкой 3-х гигов, а САС к таким не отоносится. 1000 и 5 слоев это тоже почти полтора гига. Вот если на 1000 и 1 слое добьешься аут оф мемори, тогда посмотрим. |
(0006140) vasketsov (manager) 15-03-2012 22:41 |
>Вот если на 1000 и 1 слое У меня в движении меньше 5 слоёв не бывает (не считая меток). На один экран сейчас влазит 54 тайла - итого даже 20-ти экранов нет, и 1000 готова. В общем это конечно мало, да и ограничений-то как бы нет в программе. |
(0006149) vdemidov (manager) 16-03-2012 05:04 |
>На один экран сейчас влазит 54 тайла - итого даже 20-ти экранов нет, и 1000 готова. Увы. Поэтому и говорю, что нужно делать дополнительно кэширование нераспакованных тайлов на уровне тайлохранилища. И еще. Используемый сейчас кэш, очень тупой и время поиска линейное от количества элементов в нем. То есть чем больше, тем медленее. Поэтому максимальное разумное значение 300-500 тайлов на слой. > В общем это конечно мало, да и ограничений-то как бы нет в программе. Ну надо конечно сделать подсчет размера кэша и ограничение по суммарному размеру, но ИМХО сложно, трудоемко и не сильно критично. |
(0006229) vdemidov (manager) 20-03-2012 15:21 |
Добавил ограничение на максимальный размер кэша в памяти. |
Issue History | |||
Date Modified | Username | Field | Change |
15-03-2012 16:51 | vasketsov | New Issue | |
15-03-2012 17:23 | Garl | Note Added: 0006119 | |
15-03-2012 17:24 | Garl | Relationship added | related to 0001215 |
15-03-2012 17:32 | vasketsov | Note Added: 0006120 | |
15-03-2012 17:45 | Garl | Note Added: 0006121 | |
15-03-2012 17:51 | vasketsov | Note Added: 0006122 | |
15-03-2012 22:08 | vdemidov | Note Added: 0006133 | |
15-03-2012 22:08 | vdemidov | Relationship deleted | related to 0001215 |
15-03-2012 22:17 | vasketsov | Note Added: 0006136 | |
15-03-2012 22:22 | vdemidov | Note Added: 0006137 | |
15-03-2012 22:41 | vasketsov | Note Added: 0006140 | |
16-03-2012 05:04 | vdemidov | Note Added: 0006149 | |
20-03-2012 15:21 | vdemidov | Note Added: 0006229 | |
20-03-2012 15:21 | vdemidov | Status | new => resolved |
20-03-2012 15:21 | vdemidov | Fixed in Version | => 120808 |
20-03-2012 15:21 | vdemidov | Resolution | open => fixed |
20-03-2012 15:21 | vdemidov | Assigned To | => vdemidov |
24-03-2012 21:39 | vdemidov | Target Version | => 120808 |
10-10-2012 11:47 | Tolik | Status | resolved => closed |
My View | View Issues | Change Log | Roadmap | Search |
Copyright © 2007 - 2024 SAS.Planet Team |