powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Простейший менеджер памяти на базе VirtualAlloc
90 сообщений из 90, показаны все 4 страниц
Простейший менеджер памяти на базе VirtualAlloc
    #40136192
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Необходима реализация простейшего менеджера памяти на базе VirtualAlloc. Чтобы не использовать выделение памяти средствами Delphi или FastMM, а обращаться напрямую к операционной системе. Потому что в приложении много багов, которые портят память. Выделение кусков средствами операционной системе должно помочь вызывать Access Violation если что-то пойдет не так.

Как я понимаю, выглядит это примерно так:
https://www.gunsmoker.ru/2009/01/blog-post.html

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
type
  // В старых Delphi
  TMemoryManager = record
    GetMem: function(Size: Integer): Pointer;
    FreeMem: function(P: Pointer): Integer;
    ReallocMem: function(P: Pointer; Size: Integer): Pointer;
  end;
 
  // В новых Delphi
  TMemoryManagerEx = record
    { Базовая (обязательная) функциональность }
    GetMem: function(Size: Integer): Pointer;
    FreeMem: function(P: Pointer): Integer;
    ReallocMem: function(P: Pointer; Size: Integer): Pointer;
    { Дополнительная (опциональная) функциональность }
    AllocMem: function(Size: Cardinal): Pointer;
    RegisterExpectedMemoryLeak: function(P: Pointer): Boolean;
    UnregisterExpectedMemoryLeak: function(P: Pointer): Boolean;
  end;



но примера реализации этих методов на базе VirtualAlloc найти не могу ...
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136195
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SafeMM
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136196
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Выделение кусков средствами операционной системе должно помочь вызывать Access Violation если что-то пойдет не так.
Не поможет. VirtualAlloc выделяет память страницами. Размер страницы - 4096 байт. Т.е. если вы запросили 10 байт, а обратились к 3000, то никто вам ничего не скажет.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136197
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
Наталья87
Выделение кусков средствами операционной системе должно помочь вызывать Access Violation если что-то пойдет не так.
Не поможет. VirtualAlloc выделяет память страницами. Размер страницы - 4096 байт. Т.е. если вы запросили 10 байт, а обратились к 3000, то никто вам ничего не скажет.


Тут дело скорее в том - чтобы один кусок программы не мог портить память, выделенную другим куском программы.

В этом случае VirtualAlloc поможет.

Наоборот, есть еще идея - обматывать выделяемые куски памяти "одеялом". То есть выделять вначале пару килобайт, потом запрашиваемый объем памяти, умноженный на 3 (рабочая область посередине), потом еще пару килобайт. Чтобы глючный код мог немного промахиваться и это не приводило к падению приложения.

В случае FastMM или других разделяемых менеджеров памяти фактически любой баг в каком-нибудь потоке или таймере может испортить важную память основного потока и приложение упадёт.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136198
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dmitry Arefiev
SafeMM


Работает под Delphi 7. Но увы, проект с ним вообще не запускается под Delphi XE8. И еще - он какой-то медленный очень.
Там много функций для отладки - но тут речь не про отладку а про Release-приложение. Есть в приложении баги или нет - другой вопрос - но нужно минимизировать вероятность падения Release-приложения по причине багов.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136199
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Наоборот, есть еще идея - обматывать выделяемые куски памяти "одеялом". То есть выделять вначале пару килобайт, потом запрашиваемый объем памяти, умноженный на 3 (рабочая область посередине), потом еще пару килобайт. Чтобы глючный код мог немного промахиваться и это не приводило к падению приложения.
А, понял. Цель не исправить ошибки, а завуалировать их
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136201
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
Наталья87
Наоборот, есть еще идея - обматывать выделяемые куски памяти "одеялом". То есть выделять вначале пару килобайт, потом запрашиваемый объем памяти, умноженный на 3 (рабочая область посередине), потом еще пару килобайт. Чтобы глючный код мог немного промахиваться и это не приводило к падению приложения.
А, понял. Цель не исправить ошибки, а завуалировать их


Исправлять можно у себя на компьютере. Пользователю зачем ошибки видеть?
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136204
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кроме SafeMM ни один менеджер памяти не пережил такой код:

Код: pascal
1.
2.
3.
4.
5.
6.
var
   xxx: array of byte;
begin
   setlength(xxx, 100);
   for ii:=100 to 200000 do
      xxx[ii] := 90;



В случае с SafeMM выдало Access Violation, но приложение не упало!
Но SafeMM слишком медленный, поэтому и хотелось бы реализации на базе стандартных функций VirtualAlloc.
Я думаю, поскольку память VirtualAlloc выделяется системой - подобные ошибки или пройдут незамеченными или вызовут Access Violation, но не будут валить приложение.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136205
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
_Vasilisk_
пропущено...
А, понял. Цель не исправить ошибки, а завуалировать их


Исправлять можно у себя на компьютере. Пользователю зачем ошибки видеть?


Отсутствие ошибки порождает у пользователя уверенность что программа работает в штатном режиме. Если выдается адекватное сообщение об ошибке с кнопкой послать отчет разработчику то это нормально.
Вообще странный подход конечно, ну да Ваше дело.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136206
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все дело в том, что SafeMM не работает с модулями IdHttp, IdFtp.
Экспериментальным путем было проверено, что дело не в моем проекте, а в этих модулях.

Есть вот такой код - который нужно переписать с HeapAlloc на VirtualAlloc.



Код: pascal
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.
UNIT WindowsMM;
INTERFACE
USES Windows;
IMPLEMENTATION    
type
   TMInteger = Integer;
   SIZE_T = Integer;
var
   gHeap: THandle;

function NewGetMem({$IFNDEF D2010}DataSize: TMInteger{$ELSE}DataSize: NativeInt{$ENDIF}): Pointer;
begin
   if DataSize<=0 then begin
      Result := nil;
      Exit;
   end;
//   Result := VirtualAlloc(nil, DataSize,MEM_COMMIT, PAGE_READWRITE);
   Result := HeapAlloc(gHeap, 0, DataSize);
end;


function NewFreeMem(DataPtr: Pointer): Integer;
begin
   if DataPtr=nil then begin
      Result := 0;
      Exit;
   end;
   HeapFree(gHeap, 0, DataPtr);
//   VirtualFree(DataPtr, 0, MEM_RELEASE);
   Result := 0;
end;

function NewReallocMem(DataPtr: Pointer; {$IFNDEF D2010}DataSize: TMInteger{$ELSE}DataSize: NativeInt{$ENDIF}): Pointer;
begin
   if (DataPtr=nil) or (DataSize<=0) then begin
      Result := nil;
      Exit;
   end;
   Result := HeapRealloc(gHeap, 0, DataPtr, DataSize);
end;




const
   HeapCompatibilityInformation = 0;
   HeapEnableTerminationOnCorruption = 1;
   HEAP_LFH = 2;
var
   HeapSetInformation: function(
      HeapHandle: THandle;
      HeapInformationClass: ULONG;
      HeapInformation: pointer;
      HeapInformationLength: SIZE_T
   ): BOOL; stdcall;

   

procedure InitLowFragmentationHeap(AHeap :THandle);
var
   vModule :HMODULE;
   vHeapInformation :ULONG;
begin
   vModule := GetModuleHandle(kernel32);
   if vModule<>0 then
      @HeapSetInformation := GetProcAddress(vModule, 'HeapSetInformation');
   if Assigned(HeapSetInformation) then begin
      vHeapInformation := HEAP_LFH;
      HeapSetInformation(AHeap, HeapCompatibilityInformation, @vHeapInformation, SizeOf(vHeapInformation));
   end;
end;



const
   DebugMemMgr: TMemoryManager = (
      GetMem    : NewGetMem;
      FreeMem   : NewFreeMem;
      ReallocMem: NewReallocMem
   );
var
   OldMemMgr: TMemoryManager;
   ManagerInstalled: Boolean = False;

procedure InstallMemoryManager;
begin
   if not ManagerInstalled then begin
      GetMemoryManager(OldMemMgr);
      SetMemoryManager(DebugMemMgr);
      gHeap := GetProcessHeap;
      InitLowFragmentationHeap(gHeap);
      ManagerInstalled := True;
   end;
end;

procedure DeinstallMemoryDebugManager;
begin
   if ManagerInstalled then begin
      SetMemoryManager(OldMemMgr);
      ManagerInstalled := False;
   end;
end;



INITIALIZATION
   InstallMemoryManager;
FINALIZATION
  DeinstallMemoryDebugManager;
END.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136225
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ладно, попробую переделать SafeMM. Идея в том, чтобы выделять большой защищённый блок в 64Кб на каждый запрос по выделению. памяти.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136275
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код менеджера после переделывания. Максимально минимизированный и на базе SafeMM. Большой проект на этом менеджере работает и запускается на Delphi 7.

Пустой проект с 1 формой на Delphi XE8 тоже работает. Но стоит подключить 2 модуля

USES IdFtp, IdHttp;

и проект не запускается - завершаясь с ошибкой Runtime Error 216 at00405353
Иногда выходит
access violation at address 00000000

То же самое с исходным SafeMM - стоит подключить модули

USES IdFtp, IdHttp;

и при запуске приложения с 1 формой выходит ошибка

access violation at address 00000000

Как заставить SafeMM работать с родными Delphi-модулями IdHttp, IdFtp или навскидку есть ли очевидные баги в модуле ниже?




Код: pascal
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.
UNIT WndMM;
INTERFACE
{$IF RTLVersion >= 18.0}
   {$DEFINE MEMORY_MANAGER_EX}
{$IFEND}
              
function SafeGetMem(size: integer): pointer;
function SafeFreeMem(p: pointer): integer;
function SafeReallocMem(p: pointer; size: integer): pointer;
function SafeAllocMem(size: cardinal): pointer;

const
{$IFDEF MEMORY_MANAGER_EX}
   SafeMemoryManager: TMemoryManagerEx = (
      GetMem: SafeGetMem;
      FreeMem: SafeFreeMem;
      ReallocMem: SafeReallocMem;
      AllocMem: SafeAllocMem;
      RegisterExpectedMemoryLeak: nil;
      UnregisterExpectedMemoryLeak: nil;
   );
{$ELSE}
   SafeMemoryManager: TMemoryManager = (
      GetMem: SafeGetMem;
      FreeMem: SafeFreeMem;
      ReallocMem: SafeReallocMem;
   );
type
   TMemoryManagerEx = TMemoryManager;
{$ENDIF}

IMPLEMENTATION
USES Windows;
type
   PBlockInfo = ^TBlockInfo;
   TBlockInfo = record
      start: pointer;
      size: cardinal;
   end;
var
   fCritical: TRTLCriticalSection;

function offset(const p: pointer; const addon: integer): pointer;
begin
   result := pointer( cardinal(p) + addon );
end;

function SafeGetMem(size: integer): pointer;
var
   block: PBlockInfo;
   size2, BlockSize: cardinal;
begin
   size2 := size + sizeof(TBlockInfo);

   BlockSize := size2 div 4096;
   if size2 mod 4096>0 then inc(BlockSize);
   BlockSize := BlockSize*4096;

   block := VirtualAlloc(nil, BlockSize, MEM_COMMIT, PAGE_READWRITE);
   block.start := offset(block, sizeof(TBlockInfo));
   block.size := size;

   result := block.start;
end;

function SafeAllocMem(size: cardinal): pointer;
begin
   result := SafeGetMem(size);
end;

function min(const i1, i2: integer): integer;
begin
   result := i1;
   if i2<result then result := i2;
end;

function SafeFreeMem(p: pointer): integer;
begin
   p := offset(p, -sizeof(TBlockInfo));
   VirtualFree(p, 0, MEM_RELEASE);
   result := 0;
end;

function SafeReallocMem(p: pointer; size: integer): pointer;
var
   block: PBlockInfo;
   BlockSize: integer;
begin
   block := offset(p, -sizeof(TBlockInfo));
   result := SafeAllocMem(size);
   BlockSize := min(block.size, size);
   Move(p^, result^, BlockSize);
   SafeFreeMem(p);
end;

INITIALIZATION
   InitializeCriticalSection(fCritical);
FINALIZATION
   DeleteCriticalSection(fCritical);
END.





Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
UNIT WndMMInstall;
INTERFACE
IMPLEMENTATION
USES WndMM;
var
  FOldManager: TMemoryManagerEx;

procedure InstallSafeMemoryManager;
begin
   GetMemoryManager(FOldManager);
   SetMemoryManager(SafeMemoryManager);
end;

procedure UninstallSafeMemoryManager;
begin
   SetMemoryManager(FOldManager);
end;

INITIALIZATION
   InstallSafeMemoryManager;
FINALIZATION
   UninstallSafeMemoryManager;
END.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136278
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
есть ли очевидные баги в модуле ниже?

Вангую, что нужно сделать заглушки для:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
   SafeMemoryManager: TMemoryManagerEx = (
      GetMem: SafeGetMem;
      FreeMem: SafeFreeMem;
      ReallocMem: SafeReallocMem;
      AllocMem: SafeAllocMem;
      RegisterExpectedMemoryLeak: nil;
      UnregisterExpectedMemoryLeak: nil;
   );
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136282
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kazantsev Alexey
Наталья87
есть ли очевидные баги в модуле ниже?

Вангую, что нужно сделать заглушки для:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
   SafeMemoryManager: TMemoryManagerEx = (
      GetMem: SafeGetMem;
      FreeMem: SafeFreeMem;
      ReallocMem: SafeReallocMem;
      AllocMem: SafeAllocMem;
      RegisterExpectedMemoryLeak: nil;
      UnregisterExpectedMemoryLeak: nil;
   );



Спасибо, помогло. И SafeMM после данного дополнения чудесным образом заработал.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136467
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Экспериментальным путем было проверено, что дело не в моем проекте, а в этих модулях.
Точно вам говорю - это ошибка компилятора.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136644
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
Наталья87
Экспериментальным путем было проверено, что дело не в моем проекте, а в этих модулях.
Точно вам говорю - это ошибка компилятора.


Интересный момент еще. Если использовать данный менеджер памяти (и выделять блоки кратные 4 Кб по каждому чиху - даже если требуется 10 байт) - при примерно 150 Мб занятой оперативной памяти (проверка Диспетчером задач на Win Xp с 4 Гб оперативы) выскакивает ошибка "Out of Memory" - хотя памяти свободной еще вагон. Видимо, есть какие-то ограничения операционной системы на количество выделяемых блоков, в какой-то момент функция VirtualAlloc перестает выделять память.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136646
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_
Наталья87
Экспериментальным путем было проверено, что дело не в моем проекте, а в этих модулях.
Точно вам говорю - это ошибка компилятора.


Вообще странно, что SafeMM поставляется без этих методов для Delphi XE+, хотя заявлено, что он должен работать на Delphi XE+. Хотя если принять, что это все-таки сторонний менеджер памяти и писали его люди, а устроен он довольно сложно внутри - в нём могут быть и ошибки и недоработки, как в любой программе.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136647
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Видимо, есть какие-то ограничения операционной системы на количество выделяемых блоков, в какой-то момент функция VirtualAlloc перестает выделять память.

Это называется фрагментацией адресного пространства.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136665
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
при примерно 150 Мб занятой оперативной памяти (проверка Диспетчером задач на Win Xp с 4 Гб оперативы) выскакивает ошибка "Out of Memory" - хотя памяти свободной еще вагон

Оперативная память не имеет никакого отношения к выделенной памяти в программе. В оперативной памяти программа может занимать как меньше памяти, чем она выделила (чаще всего), так и больше.

Если вы хотите смотреть за потреблением памяти вашей программы, то в диспетчере задач выберите Вид / Выбрать столбцы и поставьте галку на "Объём виртуальной памяти".

Также рекомендую: https://www.gunsmoker.ru/2011/04/windows-spin-off.html
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136667
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У VirtualAlloc по умолчанию гранулярность выделения памяти - 64 кб . Это значит, что в 2 Гб адресном пространстве этой функцией можно выделить не более 32'768 блоков.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136668
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Вообще странно, что SafeMM поставляется без этих методов для Delphi XE+, хотя заявлено, что он должен работать на Delphi XE+. Хотя если принять, что это все-таки сторонний менеджер памяти и писали его люди, а устроен он довольно сложно внутри - в нём могут быть и ошибки и недоработки, как в любой программе.

SafeMM - это просто экспериментальная демка, proof-of-concept. Уж тем более не предполагается, что его будут использовать в релизе.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136669
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Не поможет. VirtualAlloc выделяет память страницами. Размер страницы - 4096 байт. Т.е. если вы запросили 10 байт, а обратились к 3000, то никто вам ничего не скажет.

Не обязательно использовать память с начала страницы. Если цель отловить overflow, то логический блок должен заканчиваться ровно на конце физического, а начинаться где-то в середине этой 4к страницы.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136673
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Но SafeMM слишком медленный, поэтому и хотелось бы реализации на базе стандартных функций VirtualAlloc.

VirtualAlloc - это функция ядра Windows. Любой вызов ядра - это очень медленно, поскольку происходит переключение пользовательского режима и режима ядра. И с этим ничего сделать нельзя, никакое переписывание кода здесь не поможет. По сути, SafeMM - это и есть минимальная обёртка к VirtualAlloc, ничего особо больше он не делает.

Поэтому общепринятая практика как раз выделять память одним большим куском, а потом логически делить его внутри пользовательского режима, не переключаясь в режим ядра.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136699
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker
Наталья87
Но SafeMM слишком медленный, поэтому и хотелось бы реализации на базе стандартных функций VirtualAlloc.

VirtualAlloc - это функция ядра Windows. Любой вызов ядра - это очень медленно, поскольку происходит переключение пользовательского режима и режима ядра. И с этим ничего сделать нельзя, никакое переписывание кода здесь не поможет. По сути, SafeMM - это и есть минимальная обёртка к VirtualAlloc, ничего особо больше он не делает.

Поэтому общепринятая практика как раз выделять память одним большим куском, а потом логически делить его внутри пользовательского режима, не переключаясь в режим ядра.


Да, так и получилось в итоге.

Через мой менеджер памяти на базе VirtualAlloc работает также медленно (а то и еще медленнее), чем через SafeMM. При этом и памяти жрет больше, чем SafeMM (и приложение по причине OutOfMemory поэтому вылетает даже на 64-разрядных сборках). Т. к. SafeMM хоть и использует агрессивно VirtualAlloc и VirtualProtect, выделяя в разы больше памяти, чем нужно - но все же для мелких блоков он не использует VirtualAlloc.

Попробую еще для интереса не по 4 Кб, а сразу по 64 Кб выделять. Хуже судя по всему не будет - просто Диспетчер Задач будет отображать реальный объем потребляемой памяти.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136701
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker
_Vasilisk_
Не поможет. VirtualAlloc выделяет память страницами. Размер страницы - 4096 байт. Т.е. если вы запросили 10 байт, а обратились к 3000, то никто вам ничего не скажет.

Не обязательно использовать память с начала страницы. Если цель отловить overflow, то логический блок должен заканчиваться ровно на конце физического, а начинаться где-то в середине этой 4к страницы.


Для отлова ошибок есть уже готовые SafeMM и FastMM. Но первый слишком медленный и скорее для Debug, а не для Release, хотя с задачей не допустить падения программы и повреждения памяти кривым кодом справляется прекрасно. Второй как-то плохо защищает память от кривого кода .

Цель немного другая для Release-сборок. И состоит не только в том, чтобы отловить ошибки.

Цель именно в том, чтобы ошибки в программе не приводили к повреждению памяти, последующим глюкам а то и падению приложения (у клиентов на Release-сборке).

Как я полагаю - этого можно добиться либо используя агрессивные методы отлова некорректного доступа к памяти вроде SafeMM (но проблема в том, что SafeMM слишком медленный). Либо не отлавливать некорректный доступ к памяти, а просто выделять памяти больше, чем нужно, помещая данные в середину и оборачивая "одеялом". Чтобы как было как танковая броня - ошибки в одном месте программы не приводили к повреждению памяти других участков программы.

Чтобы не тормозило и не потребляло горы памяти - очевидно, делать надо это не с помощью VirtualAlloc, а с помощью HeapAlloc. Если просто выделять больше памяти, чем нужно и не ловить ошибки - замедление получается всего на 30% - при этом я полагаю, это должно защищать от порчи памяти.

И еще - было принято решение включить Range Check Error и Overflow Check. На Release сборках в том числе. По сути они не так уж сильно замедляют работу программы, как SafeMM, а толку в плане защиты памяти на практике от них немало.

Если можно - поясните, пожалуйста, в чем я не права и заблуждаюсь.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136703
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Цель именно в том, чтобы ошибки в программе не приводили к повреждению памяти, последующим глюкам а то и падению приложения (у клиентов на Release-сборке)

Для того, чтобы ошибки в программе не приводили к таким последствиям у клиентов на release-сборке, их нужно отлавливать и исправлять до этого момента. Соответствующий процесс называется тестированием и отладкой. Пытаться микшировать такие проблемы у клиентов - это примерно как лечить мёртвого припарками.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136704
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Наталья87
Цель именно в том, чтобы ошибки в программе не приводили к повреждению памяти, последующим глюкам а то и падению приложения (у клиентов на Release-сборке)

Для того, чтобы ошибки в программе не приводили к таким последствиям у клиентов на release-сборке, их нужно отлавливать и исправлять до этого момента. Соответствующий процесс называется тестированием и отладкой. Пытаться микшировать такие проблемы у клиентов - это примерно как лечить мёртвого припарками.


Так оно делается, ошибки периодически отлавливаются и фиксятся. Но к сожалению, не получается исправить их все. А клиенты жалуются, что ПО периодически (например, раз в неделю, что фиг отловишь) глючит и вылетает.

Приложение состоит из 500 000 строк кода, найти что именно глючит и портит память не получается. Ставить Release-сборки с SafeMM тоже по причине замедления работы ПО в несколько раз. Поэтому и хочется понять, что можно сделать кроме Range Check и Overflow Check - чтобы защитить память - но сильно при этом не замедлить программу.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136706
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Поэтому и хочется понять, что можно сделать кроме Range Check и Overflow Check - чтобы защитить память - но сильно при этом не замедлить программу.
имхо, тут программист нужен! ©
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136711
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПриложение состоит из 500 000 строк кода, найти что именно глючит и портит память не получается. Ставить Release-сборки с SafeMM тоже по причине замедления работы ПО в несколько раз. Поэтому и хочется понять, что можно сделать кроме Range Check и Overflow Check - чтобы защитить память - но сильно при этом не замедлить программу.

Для начала организовать показ стека в сообщении об ошибках
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136713
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GunSmoker

Если вы хотите смотреть за потреблением памяти вашей программы, то в диспетчере задач выберите Вид / Выбрать столбцы и поставьте галку на "Объём виртуальной памяти".


Увы, но при использовании VirtualAlloc-менеджера с блоками, кратными 4 Кб на каждый чих - в колонке "Виртуальная память" показывает также всего примерно 150 Мб - хотя память уже закончилась и вовсю сыпется "Out of memory".

Но вот если выделять блоками не по 4 Кб, а по 64 Кб - как и предполагалось, момент "Out of memory" наступает примерно при тех же условиях (не раньше и не позже), но зато в колонке "Виртуальная память" показывает реально потребляемый объем (ну или близко к тому).

В общем, с VirtualAlloc эксперименты закончились. Осталось понять, как защитить память на Release-сборках от глюков в программе и от случайных ошибок и падений ПО примерно раз в неделю.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136715
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87Осталось понять, как защитить память на Release-сборках от глюков в программе и
от случайных ошибок и падений ПО примерно раз в неделю.

Обычно для этого используют code review и уже названные дампы падения, но в
вашем случае это бесперспективняк.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136719
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Увы, но при использовании VirtualAlloc-менеджера с блоками, кратными 4 Кб на каждый чих - в колонке "Виртуальная память" показывает также всего примерно 150 Мб - хотя память уже закончилась и вовсю сыпется "Out of memory".

Kazantsev Alexey
Это называется фрагментацией адресного пространства.

Когда вы выделяете только 4 кб, то выделяется ровно одна страница памяти (4 кб), но память с 5-го по 64 кб оказывается недоступной (unused), поскольку следующий блок можно выделить только начиная с 64-го кб.

Изучать раскладку памяти приложения можно с помощью VMMap .
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136730
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По итогу - в попытках имитировать ошибки в программе, обращаясь к случайным адресам памяти и записывая туда какие-либо значения - лучше всего показал SafeMM, героически отражая атаки, с ним дольше всего программа не падала.

Как стандартный менеджер памяти, так и FastMM в этом случае сдались гораздо быстрее и приложение упало быстро.

Хорош, получается, SafeMM - но медленный. Вот бы его как-нибудь ускорить ...
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136736
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сама тема невероятно удивительная. Попытка укрепить изделие из.... и палок, намазав побольше ..... Для начала надо выяснить причины падения (емли их много) то самую частую и устранить. Мой хрустальный шар говорит мне что большая часть программы - копипаст. Это означает, что ошибку во множестве мест можно будет починить автозаменой. Но тут конечно программист нужен
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136742
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Michael Longneck
Для начала надо выяснить причины падения (емли их много) то самую частую и устранить


Так вот никак не получается уже больше, чем полгода. Падает редко - поэтому сложно отловить и устранить.

Поэтому и возникает идея, как защитить память, не снизив при этом сильно скорость программы. Потому что пользователям нужен стабильный продукт уже сейчас, а не в далеком будущем, когда баги будут устранены.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136747
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael LongneckСама тема невероятно удивительная. Попытка укрепить изделие из.... и палок,
намазав побольше .....

Как и любая другая тема данного топикстартера. "Фирменный стиль", так сказать...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136748
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Так вот никак не получается уже больше, чем полгода.

Вам уже не раз сказали: для этого нужен программист. Нужно организовать нормальный процесс тестирования. Сделать хотя бы пару десятков сценариев основных операций и гонять их по кругу в тестовой версии, реагируя на замеченные дефекты работы с памятью. Ещё было бы очень нехило, чтобы программист сделал поверхностный code review этим страшным и ужасным 500.000 строк - довольно вероятно, что он ткнёт пальцем со словами "вот это хреновая практика, надо переделать везде". И в целом я примерно на 99% уверен, что если бы полгода назад программист взялся бы за эту работу - то сейчас в приложении вместо 500.000 глючащих строк было бы 200.000 отлаженных.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136767
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Наталья87
Так вот никак не получается уже больше, чем полгода.

Вам уже не раз сказали: для этого нужен программист. Нужно организовать нормальный процесс тестирования. Сделать хотя бы пару десятков сценариев основных операций и гонять их по кругу в тестовой версии, реагируя на замеченные дефекты работы с памятью. Ещё было бы очень нехило, чтобы программист сделал поверхностный code review этим страшным и ужасным 500.000 строк - довольно вероятно, что он ткнёт пальцем со словами "вот это хреновая практика, надо переделать везде". И в целом я примерно на 99% уверен, что если бы полгода назад программист взялся бы за эту работу - то сейчас в приложении вместо 500.000 глючащих строк было бы 200.000 отлаженных.


Проблема еще в том, что приложение до этого работало почти 10 лет - и немного подглючивало - но терпимо и в рамках нормы. А в последнее время ошибки памяти и вылеты приняли какой-то прямо зверский вид, вылетать и глючить стало чаще, даже старый функционал, который вроде бы не менялся. Причем непонятно, в какой версии это началось, все происходило как-то постепенно.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136772
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Более того, эту закономерность можно проследить из Ваших топиков с примерами
кода. Особенно с дикими костылями, которые как раз изменяют поведение старого
кода лишь бы его не править. О чём вам каждый раз говорят. Но продолжайте стоять
на своём, это даже любопытно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136775
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторнемного подглючивало - но терпимо и в рамках нормы
в мемориз
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136779
Фотография DarkMaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87

Проблема еще в том, что приложение до этого работало почти 10 лет - и немного подглючивало - но терпимо и в рамках нормы. А в последнее время ошибки памяти и вылеты приняли какой-то прямо зверский вид, вылетать и глючить стало чаще, даже старый функционал, который вроде бы не менялся. Причем непонятно, в какой версии это началось, все происходило как-то постепенно.


Боюсь спросить - в пределах нормы - это как? Что вы там такое считаете, что вам память вагонами нужна? Возможно стоит поменять подход и крутить расчеты НЕ выделяя дополнительную память, а переиспользуя выделенную?
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136788
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DarkMaster
Наталья87

Проблема еще в том, что приложение до этого работало почти 10 лет - и немного подглючивало - но терпимо и в рамках нормы. А в последнее время ошибки памяти и вылеты приняли какой-то прямо зверский вид, вылетать и глючить стало чаще, даже старый функционал, который вроде бы не менялся. Причем непонятно, в какой версии это началось, все происходило как-то постепенно.


Боюсь спросить - в пределах нормы - это как?


Ну если, например, вылетает раз в полгода, глючит иногда. У 5% пользователей. То в пределах нормы. А в последнее время прямо вал обращений - программа глючит, падает раз в неделю, причем чуть ли не у половины пользователей. И фиг знает, в чем там может быть дело. Некоторые просят перехода на старую версию.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136789
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наталья87,

предлагаю ход конём: при падении перезапускать приложение. Майкрософт так и делает.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136801
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лучше Windows перезапускать
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136802
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот мой защищенный менеджер памяти. Защищен от случайных промахов за границы массивов. Правда, не защищен от обращения по старым ссылкам ранее выделенной памяти. Будем надеяться этого совместно с Range Check и Overflow Check будет достаточно, чтобы приложение перестало падать. Работает в 2 раза медленнее стандартного и FastMM, но быстрее, чем SafeMM, современные компы потянут, к тому же SQL-запросы не будут работать медленнее, т. к. их выполняет не программа, а Firebird поэтому общее замедление пользователь может и не почувствовать. Пока у меня на компьютере не глючит, будем тестировать на пользователях.

Код: pascal
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.
UNIT NatalyMM;
INTERFACE
USES Windows;
IMPLEMENTATION
type
   TMInteger = Integer;
   SIZE_T = Integer;
var
   gHeap: THandle;
const
   Protector0 = 1.3; {выделяем памяти в несколько раз больше, чем нужно}
   Protector1 = 64; {резервируем это количество байт до выделяемого участка}
   Protector2 = 128; {резервируем это количество байт после выделяемого участка}

procedure GetMMAndSize(DataPtr: integer; var MM, size: integer);
begin
   MM := DataPtr-Protector1;
   size := HeapSize(gHeap, 0, pointer(MM));
end;

function NewGetMem(DataSize: integer): Pointer;
var
   MM: integer;
begin
   if DataSize<=0 then begin
      result := nil;
      Exit;
   end;

   {обернем все слоем ваты}
   MM := integer(HeapAlloc(gHeap, 0, round(Protector0*DataSize) + Protector1 + Protector2));
   result := pointer(MM+Protector1);
end;

function NewFreeMem(DataPtr: Pointer): Integer;
var
   MM, size: integer;
begin
   if DataPtr=nil then begin
      Result := 0;
      Exit;
   end;

   GetMMAndSize(integer(DataPtr), MM, Size);

   HeapFree(gHeap, 0, pointer(MM));
   result := 0;
end;

function NewReallocMem(DataPtr: Pointer; DataSize: integer): pointer;
var
   MM, size: integer;
begin
   if (DataPtr=nil) or (DataSize<=0) then begin
      Result := nil;
      Exit;
   end;

   GetMMAndSize(integer(DataPtr), MM, size);

   MM := integer(HeapRealloc(gHeap, 0, pointer(MM), round(Protector0*DataSize) + Protector1 + Protector2));
   result := pointer(integer(MM)+Protector1);
end;

const
   HeapCompatibilityInformation = 0;
   HeapEnableTerminationOnCorruption = 1;
   HEAP_LFH = 2;
var
   HeapSetInformation: function(
      HeapHandle: THandle;
      HeapInformationClass: ULONG;
      HeapInformation: pointer;
      HeapInformationLength: SIZE_T
   ): BOOL; stdcall;

procedure InitLowFragmentationHeap(AHeap :THandle);
var
   vModule: HMODULE;
   vHeapInformation :ULONG;
begin
   vModule := GetModuleHandle(kernel32);
   if vModule<>0 then
      @HeapSetInformation := GetProcAddress(vModule, 'HeapSetInformation');
   if Assigned(HeapSetInformation) then begin
      vHeapInformation := HEAP_LFH;
      HeapSetInformation(AHeap, HeapCompatibilityInformation, @vHeapInformation, SizeOf(vHeapInformation));
   end;
end;

const
   DebugMemMgr: TMemoryManager = (
      GetMem    : NewGetMem;
      FreeMem   : NewFreeMem;
      ReallocMem: NewReallocMem
   );
var
   OldMemMgr: TMemoryManager;
   ManagerInstalled: Boolean = False;

procedure InstallMemoryManager;
begin
   if not ManagerInstalled then begin
      GetMemoryManager(OldMemMgr);
      SetMemoryManager(DebugMemMgr);
      gHeap := GetProcessHeap;
      InitLowFragmentationHeap(gHeap);
      ManagerInstalled := True;
   end;
end;

procedure DeinstallMemoryDebugManager;
begin
   if ManagerInstalled then begin
      SetMemoryManager(OldMemMgr);
      ManagerInstalled := False;
   end;
end;

INITIALIZATION
   InstallMemoryManager;
FINALIZATION
   DeinstallMemoryDebugManager;
END.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136803
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
500 тысяч строк - это не очень много...
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136814
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
По итогу - в попытках имитировать ошибки в программе, обращаясь к случайным адресам памяти и записывая туда какие-либо значения - лучше всего показал SafeMM, героически отражая атаки, с ним дольше всего программа не падала.

Как стандартный менеджер памяти, так и FastMM в этом случае сдались гораздо быстрее и приложение упало быстро.

Хорош, получается, SafeMM - но медленный. Вот бы его как-нибудь ускорить ...
Я вам удивительную вещь скажу:
"SafeMM нельзя использовать в релизе, только в отладке, для поиска ошибок доступа к памяти"
Это его основная фича

Он запросто может всю память сожрать и приложение упадёт.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136821
Фотография Дегтярев Евгений
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
и приложение упадёт.

это терпимо и в рамках нормы (с)
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136833
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дегтярев Евгений,

Тут как бы в идеале для ТС: разобраться зачем нужен SafeMM(как он работает) и пофиксить баги, а не героически отражать атаки отладочным инструментом
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136841
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Справедливости ради, вполне возможно, что ресурсов фиксить баги нет, а рабочий релиз нужен вотпрямщас. При этом падения с описанной частотой приемлемы.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136846
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Fr0sT-Brutal

а рабочий релиз нужен вотпрямщас


Да, прямо в точку. Хоть как-то работающий релиз нужен позарез. Использовать старые версии годичной давности (которые меньше глючат и меньше падают) не вариант - т. к. старые версии постепенно перестают быть актуальными для пользователей ввиду недостаточного функционала. А кто уже обновился ему и вовсе назад на старые версии не перейти.



Fr0sT-Brutal

, . При этом падения с описанной частотой приемлемы.


А кто ж их спрашивать будет, эти падения - приемлемы они или нет? Программа падает и никого не спрашивает, приемлемо это или нет.

В последние дни вроде падать стало реже. Не знаю, благодаря моему менеджеру памяти, который выделяет память с запасом или благодаря включению в релизы Range Check Error и Overflow Check Error.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136851
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
Справедливости ради, вполне возможно, что ресурсов фиксить баги нет, а рабочий релиз нужен вотпрямщас.

Угу, оно всегда так. Делать хорошо - ресурсов нет, а делать плохо, мучиться, переделывать и в итоге тратить в десять раз больше - они откуда-то находятся. И что самое забавное - в результате ресурсов никогда нет, потому что они всегда уходят на борьбу с ранее созданными хренями. И так продолжается до тех пор, пока результат просто волевым усилием не спускается в унитаз, и вместо него с нуля не делается такое же дерьмо, только на другой технологии. Часто теми же людьми - что, собственно, и обеспечивает "такое же дерьмо".
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136861
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может это использовать https://bitbucket.org/shadow_cs/delphi-leakcheck
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40136990
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ziv-2014,

да у них не утечки, у них скорее всего доступ к убитым объектам по типу

Код: pascal
1.
2.
3.
Obj.Free;
...
Obj.a := 2;



SafeMM + EuricaLog например, как раз то, что доктор прописал
искать и править

ну и спич возникнет как всегда вокруг .Free-FreeAndNil()
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137003
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я когда искал утечки с помощью fastmm был вынужден делать freeandnil у объектов так как fastmm показывал утечку указателя, при том что сам объект был убит. так с тех пор и привык им пользоваться
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137007
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
энди> был вынужден делать freeandnil у объектов так как fastmm
энди> показывал утечку указателя, при том что сам объект был убит

Для обычных объектов или интерфейсов?
Обычно всякие чеккеры (в т.ч. в других ЯП
и средах, типа валгринд и пр.) работают по
парам Create-Free (ну или malloc-delete).
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137012
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам,

они просто не знаю про FreeAndNil
хотя правды для: автопоинты другие костыли имеют

SafeMM жёстче работает, он просто память не освобождает, а доступы к ней все запрещает на уровне страниц
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137015
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам
энди> был вынужден делать freeandnil у объектов так как fastmm
энди> показывал утечку указателя, при том что сам объект был убит

Для обычных объектов или интерфейсов?
Обычно всякие чеккеры (в т.ч. в других ЯП
и средах, типа валгринд и пр.) работают по
парам Create-Free (ну или malloc-delete).


обычные объекты, я вообще интерфейсами практически не пользуюсь
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137020
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)да у них не утечки, у них скорее всего доступ к убитым объектам по типу

Бери выше, у них рандомный доступ к памяти: 22437654
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137036
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
энди> обычные объекты

Это странно. AFAIU, это баг и если у тебя
воспроизводится на чистом проекте - вышли
им, пусть правят.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137041
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

kealon(Ruslan)да у них не утечки, у них скорее всего доступ к убитым объектам по типу

Бери выше, у них рандомный доступ к памяти: 22437654


Этот злополучный модуль переписан. Глюков стало меньше. При включении Range Check Error еще меньше. Но к сожалению, глюков все еще много. Особенно в сборке, которая на XE8, прямо какой-то глюконат. На Delphi 2007 глюков меньше, но в последнее время и там почему-то стали чаще. Да, мы все еще продолжаем пилить проект на D2007, время от времени собирая на XE8.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137103
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kealon(Ruslan)
Гаджимурадов Рустам,

они просто не знаю про FreeAndNil
хотя правды для: автопоинты другие костыли имеют

SafeMM жёстче работает, он просто память не освобождает, а доступы к ней все запрещает на уровне страниц


Если код кривой, но давно работающий и в нем тупо переписать Free на FreeAndNil - пробовали. Но в этом случае иногда начинают вылезать баги, которых раньше не было (уже не помню пример кода - но такая ситуация была уже - когда срочно пришлось вернуть обратно Free). Так что если нет в планах рефакторить код - лучше не заменять просто так Free на FreeAndNil. А новый код, наверное, лучше писать с FreeAndNil.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137104
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Но в этом случае иногда начинают вылезать баги, которых раньше не было

Да-да Не было
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137123
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Наталья87
Но в этом случае иногда начинают вылезать баги, которых раньше не было

Да-да Не было


FreeAndNil - хрень полная, которая только вводит в заблуждение. Пример. Есть у нас класс

Код: pascal
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.
type
   TMyClass=class
      x: array of integer;
      constructor Create;
      destructor Destroy;
      destructor Free;
   end;

constructor TMyClass.Create;
begin
   setlength(x, 10);
   x[7] := 19;
end;

destructor TMyClass.Destroy;
begin
   ShowMessage('6');
   setlength(self.x, 0);
end;

destructor TMyClass.Free;
begin
   ShowMessage('5');
   setlength(self.x, 0);
end;





Вызываем код с Free:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure TForm1.Button1Click(Sender: TObject);
var
   c: TMyClass;
begin
   c := TMyClass.Create;
   try
   finally
      c.Free;
   end;
end;



Срабатывает всё четко, выдает сообщение "5".



Теперь вызываем код с FreeAndNil:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure TForm1.Button1Click(Sender: TObject);
var
   c: TMyClass;
begin
   c := TMyClass.Create;
   try
   finally
      FreeAndNil(c);
   end;
end;



Поведение программы меняется - теперь она вообще никаких сообщений не выдает. То есть получается, метод класса Free или Destroy не отрабатывает (а ведь в этих методах могут быть методы освобождения памяти объектов, созданных классом, а не освобождать это уже утечки памяти). И самое главное - поведение программы меняется. И где в первом варианте с Free были баги? Их действительно не было, но с заменой на FreeAndNil они появились (память не освободилась, а ведь там может быть не только динамический массив, но и сложный объект и т. д.)
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137124
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
FreeAndNil - хрень полная, которая только вводит в заблуждение.
у тебя ошибка сломалась.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137127
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137128
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кажется, дошло. Во всем проекте я получается, неверно использую деструкторы. Надо писать c override .

Код: pascal
1.
2.
3.
4.
5.
TMyClass=class
   x: array of integer;
   constructor Create;
   destructor Destroy; override;
end;



Тогда и FreeAndNil будет нормально работать.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137129
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
FreeAndNil - хрень полная, которая только вводит в заблуждение.

Компьютер тоже - хрень полная. Займитесь чем-нибудь, что Вам по силам. Из соображений деликатности не буду приводить примеров, чем именно.

Наталья87
Пример. Есть у нас класс

Божечки Я, конечно, подозревал, какой код у вас в приложении, но я вас недооценил.

Наталья87
Поведение программы меняется - теперь она вообще никаких сообщений не выдает.

И причиной этому не детские ошибки, которые Вы ухитрились влепить в первых пяти строчках своего примера, а хреновый FreeAndNil Вы способны эти ошибки хотя бы найти или Вам помочь?

P.S. Способны. Ну.. уже плюс, конечно.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137133
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer

Божечки Я, конечно, подозревал, какой код у вас в приложении, но я вас недооценил.


Да я теперь сама офигеваю, как 500 тысяч строк кода (рабочего, но написанного в таком стиле) переписывать, написанных за более, чем 10 лет, на правильный стиль. Похоже, надо было раньше придти к вам, пока проект был не таким большим.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137139
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87> 500 тысяч строк кода (рабочего, но
Наталья87> написанного в таком стиле) переписывать,
Наталья87> написанных за более, чем 10 лет

1. 500 тыщ это не так уж и много, тем паче за 10 лет.
2. Не "рабочего", а запускающегося и как-то работающего.
3. Кажется, я Вам уже говорил - не учитесь методом тыка.
Вы, кажется, тогда мне что-то огрызнулись. Нет, методом
проб и ошибок тоже можно, конечно, но сильно дольше.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137148
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Кажется, дошло. Во всем проекте я получается, неверно использую деструкторы. Надо писать c override
Я, кажется, уже когда-то говорил, что не стоит игнорировать варнинги и хинты.
Все они обязаны быть исправлены.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137149
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock
Наталья87
Кажется, дошло. Во всем проекте я получается, неверно использую деструкторы. Надо писать c override
Я, кажется, уже когда-то говорил, что не стоит игнорировать варнинги и хинты.
Все они обязаны быть исправлены.


Надо, но все руки не доходят, но буду делать, тут вариантов не остается уже. У меня сейчас накопилось их в программе 2500 штук. Большинство глупые вроде "variable was declared, but never used" или "variable might not be initialized", хотя по коду четко видно, что переменная не может быть не инициализирована. Правда некоторые и по делу, но найди попробуй в такой куче, какие по делу, а какие просто так.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137156
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Надо, но все руки не доходят, но буду делать, тут вариантов не остается уже.

Если криво писать "потому что нужен релиз прямо сейчас", руки никогда не дойдут. Они так и будут вечно заняты копанием в куче не будем говорить чего.

Наталья87
У меня сейчас накопилось их в программе 2500 штук.

(Застрелился второй раз кряду). А я-то, помнится, с ужасом вспоминал, как в джуновские времена пинал своё руководство, пока не добился права исправить порядка пятисот штук, которые они наплодили в проекте. И как после этого вдруг исчезли пара десятков таинственных ошибок, которые всё не получалось исправить.

Наталья87
Большинство глупые вроде "variable was declared, but never used" или "variable might not be initialized", хотя по коду четко видно, что переменная не может быть не инициализирована. Правда некоторые и по делу, но найди попробуй в такой куче, какие по делу, а какие просто так.

Во-первых, они все по делу. Варнингов просто так в дельфе нет. Если совсем точно - я знаю только один, и я стопроцентно уверен, что у вас его не бывает. А во-вторых, не надо искать и разделять. Надо исправить все и держать по нулям. Строго и без вариантов.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137159
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
все руки не доходят
Руки не доходят до исправления ошибок? Ну, что тут скажешь.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137160
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
Правда некоторые и по делу, но найди попробуй в такой куче, какие по делу, а какие просто так.
Очень просто. Сделать так, чтобы не было кучи. Чтобы не было ни одного. Начать с первого и закончить последним.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137241
Фотография Exteris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, да. Наверное нубский вопрос.

Почему
Код: pascal
1.
2.
3.
4.
5.
6.
Obj:=TObject.Create;
try
   ...
finally
   Obj.Free;
end;

Это - ок

А вот
Код: pascal
1.
2.
3.
4.
5.
6.
try
   Obj:=TObject.Create;
   ...
finally
   Obj.Free;
end;


Это - Variable 'Obj' might not have been initialized?
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137242
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Exteris,

вставь в TMyObject.Create какой нибудь raise Exception.Create('Test') и посмотри
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137250
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot Exteris#22440507]Кстати, да. Наверное нубский вопрос.

Почему
Код: pascal
1.
2.
3.
4.
5.
6.
try
   Obj:=TObject.Create;
   ...
finally
   Obj.Free;
end;



Блин, у меня половина кода в таком стиле написана. Переписываю.

А по поводу FreeAndNil - была вчера попытка на него перейти, а также установить override для всех Destroy. Но пошло такое количество глюков (Access Violation, Range Check Error и прочее), что испугалась и пришлось версию откатить назад. Видимо, надо сразу код в правильном стиле писать, переписывать будет сложнее.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137251
Фотография Exteris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zelius
Exteris,

вставь в TMyObject.Create какой нибудь raise Exception.Create('Test') и посмотри

Ну и? Чем в этом случае поможет данный warning?
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137254
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
А по поводу FreeAndNil - была вчера попытка на него перейти, а также установить override для всех Destroy. Но пошло такое количество глюков (Access Violation, Range Check Error и прочее), что испугалась и пришлось версию откатить назад. Видимо, надо сразу код в правильном стиле писать, переписывать будет сложнее.


Access Violation у вас как раз из-за того что освобождёнными объектами пользовались, а теперь ссылки на них обнуляются и обращение по этим указателям даёт AV

поочерёдно надо делать
поправили один объект, добавили у него метод
Код: pascal
1.
procedure Free(); deprecated "Test";


и смотрите где вы его освобождаете

за денёк управитесь
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137255
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наталья87
Большинство глупые вроде (...) "variable might not be initialized", хотя по коду четко видно, что переменная не может быть не инициализирована.

Данный варнинг может быть ложным, но что-то я сомневаюсь, учитывая контекст говнософта. Скорее всего, это не ошибки глупые :) Кидай примеры, поглядим, кто там глупее - компилятор или погромист
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137262
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Exteris
Zelius
Exteris,

вставь в TMyObject.Create какой нибудь raise Exception.Create('Test') и посмотри

Ну и? Чем в этом случае поможет данный warning?
В тексте варнинга всё написано. Исчерпывающе.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137264
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Exteris
А вот
Код: pascal
1.
2.
3.
4.
5.
6.
try
   Obj:=TObject.Create;
   ...
finally
   Obj.Free;
end;



Это - Variable 'Obj' might not have been initialized?

В выделенном месте, при исключении в конструкторе, произойдет попытка освобождения объекта по мусорному указателю.
О чем варнинг и пишет: "Переменная может быть не инициализирована".
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137306
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я просто поражаюсь, как некоторые могут селёдку без водки! ©

как, не имея элементарных понятий в ООП, можно было наговнокодить такую КУЧУ?!
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137313
Фотография LocksmithPC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий

как, не имея элементарных понятий в ООП, можно было наговнокодить такую КУЧУ?!


Знаю погромистов, пишущих код смотря ролики ютюба
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137335
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
как, не имея элементарных понятий в ООП, можно было наговнокодить такую КУЧУ?!

Долго и старательно. Я вроде вчера или позавчера писал про то, что самое страшное бедствие в нашей профессии - неленивый программист.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137338
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
Мимопроходящий
как, не имея элементарных понятий в ООП, можно было наговнокодить такую КУЧУ?!
Долго и старательно. Я вроде вчера или позавчера писал про то, что самое страшное бедствие в нашей профессии - неленивый программист.

--- а куда подевались индусские программисты?
--- вошли в совет директоров M$
©
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137346
Наталья87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Мимопроходящий
как, не имея элементарных понятий в ООП, можно было наговнокодить такую КУЧУ?!

Долго и старательно. Я вроде вчера или позавчера писал про то, что самое страшное бедствие в нашей профессии - неленивый программист.


Я помню - когда начала изучать программирование в Turbo Pascal было дело. Так уже на 3-й изучения день столкнулась ограничением вроде называлось "code segment too large" или что-то подобное - размер кода больше 64 килобайт. Так получилось за счет Copy&Paste кода с последующими правками, понимание что такое циклы, файлы, константы и модули было слабое тогда. Препопадатель была в офигении - говорит ни разу с подобным не сталкивались за несколько лет - а потом через несколько дней говорит - ну значит изучайте что такое модули.

Жаль, что не сохранился этот код - но там реально был говнокод - тот код, что здесь в примерах покажется цветочками.

Получается такой код таким образом - код написан, работает, программа работает без сообщений об ошибках и не глючит - значит, всё нормально.

У нас нет времени исправлять ошибки, новый функционал надо пилить, так и живём.

Так что полмиллиона строк наговнокодить за несколько лет никаких проблем. Вопрос как его потом поддерживать, а сейчас вообще даже править страшно пусть и с лучшими намерениями вроде Free на FreeAndNil, т. к. при попытках что-то править начинает жёстко глючить.
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137372
Фотография LocksmithPC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87, 22306846 Анна Петровна, ты что ли?
...
Рейтинг: 0 / 0
Простейший менеджер памяти на базе VirtualAlloc
    #40137418
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наталья87
У нас нет времени исправлять ошибки
Это путь в небытие.
Наталья87
вообще даже править страшно пусть и с лучшими намерениями вроде Free на FreeAndNil
Это не исправит ошибок, ни одной. Разве что они станут очевиднее - сообщений о них станет больше. А потому, с Вашей точки зрения, это бессмысленно и даже вредно.
...
Рейтинг: 0 / 0
90 сообщений из 90, показаны все 4 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Простейший менеджер памяти на базе VirtualAlloc
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]