Wie die Speicher-Manager davon zu überzeugen, nicht verwendete Speicher freizugeben

StackOverflow https://stackoverflow.com/questions/4475592

  •  11-10-2019
  •  | 
  •  

Frage

In einem kürzlich erschienenen Beitrag ( Mein Programm löst nie die Erinnerung zurück. Warum? ) ich zeigen, dass bei FastMM verwenden, die Anwendung entbindet keine wesentlichen Mengen an Speicher an das System zurück. Vor kurzem habe ich ein künstliches Testprogramm um sicherzustellen, dass das Problem es ist kein Gedächtnis und dass es scheint, nur mit FastMM.

In diesem Programm, das ich schaffen und ein Objekt (das gleiche wie das in der früheren Post verwendet) 500 mal zerstören.

Die Speicheranforderungen sind ( "Privater Arbeitssatz"):

Ohne FastMM
Vor dem Ausführen der Schleife: 1,2 MB
Nach dem Ausführen der Schleife: 2,1MB

Mit FastMM (aggressiven Debug-Modus)
Vor dem Ausführen der Schleife: 2,1MB
Nach dem Ausführen der Schleife: 25MB

Mit FastMM (Freigabemodus)
Vor dem Ausführen der Schleife: 1,8MB
Nach dem Ausführen der Schleife: 3 MB

Wenn ich die Schleife mehrmals ausführen, wird der Speicherbedarf nicht erhöht. Das bedeutet, dass der nicht freigegebene Speicher wird wieder verwendet, so dies nicht ein Speicherverlust ist (ein Speicherleck des Speicherbedarf mit mehreren KB / MB bei jedem Durchlauf erhöhen würde).


Meine Fragen sind:

Wie kann ich dieses Verhalten in FastMM deaktivieren? Ist es überhaupt möglich? Ich weiß, wenn ich das Programm ohne FastMM oder mit FastMM Release Mode Release wird es moderate Mengen an RAM „verschwenden“. Aber das Deaktivieren dieses Verhalten auf Nachfrage, wird mir helfen (uns?) Speicherlecks identifizieren. Eigentlich in meinem ersten Beitrag (siehe Link) viele Leute vorgeschlagen, dass ich ein Leck habe. Die Verwirrung entstand offensichtlich nur wegen dieses Verhaltens. Nein, es ist offensichtlich, gibt es kein Leck. Es ist nur die Speicher-Manager, die großen Mengen an Speicher freizugeben verweigert.

Es wird immer den zusätzlichen Speicher freigeben? Wann? Was löst das? Kann der Programmierer auslösen es? Zum Beispiel, wenn ich weiß, dass ich eine RAM intensive Aufgabe und der Benutzer verwenden kann das Programm nicht für eine Weile beendet habe (minimieren), kann ich den RAM zurück zu dem System spülen? Was passiert, wenn der Benutzer öffnen mehrere Instanzen von meinem Programm? Werden sie nicht konkurrieren um RAM?

War es hilfreich?

Lösung 4

GELöST

Wie vorgeschlagen von Barry Kelly wird der Speicher automatisch von FastaMM freigegeben werden. Um zu bestätigen, dass dies ich crated ein zweites Programm, das viel RAM zugewiesen. Sobald Windows-RAM, Nutzung mein Programm lief Speicher auf den ursprünglichen Wert zurückgeführt.

Problem gelöst. Dank Barry.

Andere Tipps

Sie sollten nicht darüber nachdenkt, wie RAM „verschwenden“, wirklich. Denken Sie darüber nach, wie „Cachen“ nicht verwendete RAM. Die Speicher-Manager auf den ungenutzten Speicher halten, anstatt sie zurück zu dem O aus einem Grunde der Freigabe, und in der Tat haben Sie auf diesem Grunde in Frage getroffen.

Sie haben gesagt, Sie halten die gleichen Operationen in einer Schleife wieder ausgeführt wird. Wenn Sie das tun, es hat immer noch den alten Speicher zur Verfügung und es kann sofort zuweisen, anstelle von Windows für ein neues Stück von Haufen zu fragen. Dies ist einer der Tricks, dass puts die „Fast“ in „FastMM,“ und wenn es nicht tun, dass Sie Ihr Programm finden würden viel langsamer ausgeführt wird.

Sie haben keine Sorgen zu machen über die FastMM Debug-Modus Abbildung benötigen. Das ist nur für das Debuggen, und du bist nicht ein Programm gegen FullDebugMode zusammengestellt gehen zu lösen. Und der Unterschied zwischen „ohne FastMM“ und „mit FastMM Release Mode“ ist ca. 1 MB, die auf moderner Hardware vernachlässigbar ist. Für den niedrigen Preis von nur 1 zusätzlichem MB, Sie einen großen Leistungsschub bekommen. Also keine Sorge über sie.

Ein Teil von dem, was FastMM macht schnell ist, dass es einen großen Speicherblock zugewiesen wird und schnitzen kleiner gleichmäßig große Stücke aus ihm heraus. Wenn ein Teil des Blockes in Gebrauch ist, nichts davon freigegeben zurück in die OS werden kann.

Sie sind gern gesehen einen anderen Speicher-Manager verwenden. Ein Ansatz würde Weg sein alle Zuordnungen direkt an VirtualAlloc . Zuteilungen aufzurunden eine ganze Seite auf einmal zu besetzen, so dass Ihr Programm leiden können, wenn Sie viele kleine Zuweisungen haben, aber wenn man VirtualFree aufrufen, können Sie sicher sein, dass der Speicher funktioniert definitiv nicht gehören in Ihrem Programm nicht mehr.

Eine weitere Möglichkeit ist Strecke alles rund um das O Haufen. Verwenden Sie HeapAlloc . Sie können sogar ermöglichen der Low-Fragmentierung Heap für Ihr Programm (auf durch Standard ab Windows Vista), die das Betriebssystem verwendet eine Strategie ähnlich den von FastMM verwendet machen, aber es erlauben Sie, einige Fehlersuche und Analyse-Tools von Microsoft zu verwenden, um Ihr Programm der Speichernutzung im Laufe der Zeit zu verfolgen. Beachten Sie aber, dass Sie nach HeapFree nennen, noch einige Metriken, um die Speicher als zu Ihrem Programm zeigen könnten.

Neben der Arbeits Satz bezieht sich auf die Erinnerung, dass die zur Zeit in physischem RAM . Dass man beobachtet die Zahl steigen, bedeutet nicht, dass Ihr Programm mehr Speicher zugewiesen hat. Es kann einfach bedeuten, dass Ihr Programm berührt einige Speicher, die es zuvor zugeteilt worden, die aber legte in den RAM noch nicht hatte. Während der Schleife, berühren Sie, dass der Speicher und das Betriebssystem ist auf Seite auf der Festplatte noch Rückzieher nicht entschieden.

Ich verwende den folgenden als Speichermanager. Ich tue dies, weil es viel besser unter Thread-Konkurrenz als FastMM ausführt, die eigentlich eher schlecht ist. Ich weiß, dass ein skalierbares Manager wie Hoard besser wäre, aber dies ist funktioniert gut für meine Bedürfnisse.

unit msvcrtMM;

interface

implementation

type
  size_t = Cardinal;

const
  msvcrtDLL = 'msvcrt.dll';

function malloc(Size: size_t): Pointer; cdecl; external msvcrtDLL;
function realloc(P: Pointer; Size: size_t): Pointer; cdecl; external msvcrtDLL;
procedure free(P: Pointer); cdecl; external msvcrtDLL;

function GetMem(Size: Integer): Pointer;
begin
  Result := malloc(size);
end;

function FreeMem(P: Pointer): Integer;
begin
  free(P);
  Result := 0;
end;

function ReallocMem(P: Pointer; Size: Integer): Pointer;
begin
  Result := realloc(P, Size);
end;

function AllocMem(Size: Cardinal): Pointer;
begin
  Result := GetMem(Size);
  if Assigned(Result) then begin
    FillChar(Result^, Size, 0);
  end;
end;

function RegisterUnregisterExpectedMemoryLeak(P: Pointer): Boolean;
begin
  Result := False;
end;

const
  MemoryManager: TMemoryManagerEx = (
    GetMem: GetMem;
    FreeMem: FreeMem;
    ReallocMem: ReallocMem;
    AllocMem: AllocMem;
    RegisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak;
    UnregisterExpectedMemoryLeak: RegisterUnregisterExpectedMemoryLeak
  );

initialization
  SetMemoryManager(MemoryManager);

end.

Das ist keine Antwort auf Ihre Frage, aber es ist zu lang, um fit in einen Kommentar und Sie finden es vielleicht interessant App gegen diese MM zu laufen. Meine Vermutung ist, dass es die gleiche Art und Weise wie FastMM durchführt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top