SASGIS

Веб-картография и навигация


View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001220SAS.Планета[All Projects] Багpublic15-03-2012 16:5110-10-2012 11:47
Reportervasketsov 
Assigned Tovdemidov 
PrioritynormalSeveritymajorReproducibilitysometimes
StatusclosedResolutionfixed 
PlatformWindowsOSVistaOS VersionUltimate
Product Version.Nightly 
Target Version120808Fixed in Version120808 
Summary0001220: При длительном безостановочном перемещении карты возникает 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 Reproduce1. Открываем сас и для наглядности поверх него таскманагер на закладке с пмятью.
2. Сасу вписываем число кэшируемых тайлов несколько тыщ. На самом деле не так уж и много, у мну 3000.
3. Начинаем яростно елозить картой вправо-влево - наблюдаем рост сожранной памяти. В зависимости от скорости работы и количества памяти очевидно тангенс угла наклона линии может быть разный. Не останавливаемся. Может быть минут 10.
4. Когда память кончается - получаем в лицо EOutOfMemory внутри битмапки, наружу исключение вылетает уже текстом, но не суть. Возможно исключение кинется в другом месте. Значит не повезло.
5. После продолжения работы ждём и смотрил глазами в таскманагер. Как придёт мусорщик - сразу использованная память грохнется вниз до первоначальных значений.
TagsNo tags attached.
Attached Files

- Relationships

-  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

Добавил ограничение на максимальный размер кэша в памяти.

- Users who viewed this issue
User List Anonymous (2174x)
Total Views 2174
Last View 29-03-2024 05:31

- 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



Copyright © 2007 - 2024 SAS.Planet Team