Błąd Systemu. Kod: 8. Nie ma wystarczającej ilości miejsca do przetworzenia tego polecenia

Mamy kilka aplikacji Win32 (zakodowanych w Delphi 2006), w których czasami użytkownik otrzymuje komunikat o błędzie mówiący " Błąd systemu. Kod: 8. Nie ma wystarczającej ilości miejsca do przetworzenia tego polecenia.".

Ze stacktrace wygląda tak, jakby była zawsze podczas wywołania CreateWnd

Main ($1edc):
004146cc +070 app.exe SysUtils               RaiseLastOSError
00414655 +005 app.exe SysUtils               RaiseLastOSError
004ce44c +130 app.exe Controls               TWinControl.CreateWnd
00535a72 +022 app.exe cxControls             TcxControl.CreateWnd
004ce82a +016 app.exe Controls               TWinControl.CreateHandle
00553d21 +005 app.exe cxContainer            TcxContainer.CreateHandle
00586ef1 +005 app.exe cxEdit                 TcxCustomEdit.CreateHandle
005c331d +005 app.exe cxDropDownEdit         TcxCustomDropDownEdit.CreateHandle
004ceaf0 +074 app.exe Controls               TWinControl.UpdateShowing
004ceb1e +0a2 app.exe Controls               TWinControl.UpdateShowing
004cebdc +03c app.exe Controls               TWinControl.UpdateControlState
004d118a +026 app.exe Controls               TWinControl.CMVisibleChanged
004cb713 +2bb app.exe Controls               TControl.WndProc
004cf569 +499 app.exe Controls               TWinControl.WndProc
004b727d +4c1 app.exe Forms                  TCustomForm.WndProc
004cb3a0 +024 app.exe Controls               TControl.Perform
004c9f6a +026 app.exe Controls               TControl.SetVisible
004b6c46 +03a app.exe Forms                  TCustomForm.SetVisible
004baf1b +007 app.exe Forms                  TCustomForm.Show
004bb151 +14d app.exe Forms                  TCustomForm.ShowModal
007869c7 +0d3 app.exe UfrmPrice      770 +19 TfrmPrice.EditPrice
0078655d +009 app.exe UfrmPrice      628  +0 TfrmPrice.actNewBidExecute
00431ce7 +00f app.exe Classes                TBasicAction.Execute
004c2cb5 +031 app.exe ActnList               TContainedAction.Execute
004c397c +050 app.exe ActnList               TCustomAction.Execute
00431bb3 +013 app.exe Classes                TBasicActionLink.Execute
004af384 +090 app.exe Menus                  TMenuItem.Click
004b059f +013 app.exe Menus                  TMenu.DispatchCommand
004b16fe +082 app.exe Menus                  TPopupList.WndProc
004b164d +01d app.exe Menus                  TPopupList.MainWndProc
004329a8 +014 app.exe Classes                StdWndProc
7e4196b2 +00a USER32.dll                     DispatchMessageA
004bea60 +0fc app.exe Forms                  TApplication.ProcessMessage
004bea9a +00a app.exe Forms                  TApplication.HandleMessage
004becba +096 app.exe Forms                  TApplication.Run
008482c5 +215 app.exe AppName        129 +42 initialization

Nigdy nie byłem w stanie dotrzeć do sedna tego, co powoduje to i jak to się zdarza dość rzadko, nie byłem zaniepokojony, ale chciałbym dowiedzieć się, co powoduje to i mam nadzieję naprawić to...

EDIT: Full Stacktrace

EDIT 2: Więcej informacji... Klient, który doświadczył tego dzisiaj, miał moją aplikację zainstalowaną przez około 4 miesiące i działa na swoim komputerze 8 godzin dziennie. Problem pojawił się dopiero dzisiaj i pojawiał się ponownie, mimo że zabił moją aplikację i uruchomił ją ponownie. Żadna z innych aplikacji w jego systemie nie zachowywała się dziwnie. Po ponownym uruchomieniu problem znika całkowicie. Czy to wskazuje na niedobór sterty, że Steve wspomina?

EDIT 3: ciekawy wpis na blogu msdn tutaj i tutaj na temat sterty pulpitu. Choć nie jestem pewien, czy to jest przyczyną problemu, to na pewno wygląda prawdopodobne.

Author: Marius, 2009-02-03

7 answers

Jeśli twój program używa wielu zasobów systemu windows, może to być niedobór zasobów.

Istnieje wpis rejestru, który można zwiększyć, aby zwiększyć rozmiar sterty dla XP. Dla Vista Microsoft ustawia już wartość domyślną wyższą. Zalecam zmianę domyślnego 3072 na co najmniej 8192.

Ta informacja jest udokumentowana w ms Knowledge Base (lub Szukaj "Out of Memory"). Dodatkowe szczegóły dotyczące wartości parametrów można znaleźć w artykule KB184802 .

Proponuję przeczytać artykuł bazy wiedzy, ale podstawowe informacje na temat zmiany to:

  1. Uruchom edytor rejestru (REGEDT32.EXE).

  2. Z poddrzewa HKEY_ LOCAL_MACHINE przejdź do następującego klucza:

    \System\CurrentControlSet\Control\Session Manager\SubSystem
    
  3. Po prawej stronie ekranu kliknij dwukrotnie klawisz:

    windows 
    
  4. W wyskakującym oknie zobaczysz zaznaczone bardzo długie pole. Przesuń kursor w pobliżu początku ciągu znaków szukanie tego (wartości mogą się różnić):

    SharedSection=1024,3072,512
    
  5. SharedSection określa sterty systemowe i pulpitowe w następującym formacie: SharedSection=xxxx,yyyy,zzz Gdzie xxxx określa maksymalny rozmiar sterty systemowej (w kilobajtach), yyyy określa rozmiar sterty pulpitu, a zzz określa rozmiar sterty pulpitu dla "nieinteraktywnej" stacji okien.

  6. Zmień tylko wartość yyyy na 8192 (lub większą) i naciśnij OK.

  7. Wyjdź z rejestru Edytor i uruchom ponownie komputer, aby zmiana weszła w życie.

Powodzenia.
 27
Author: Steve Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-30 16:58:19

W rzeczywistości jest to problem z tabelą ATOM. zgłosiłem ten problem do Embarcadero ponieważ sprawia mi to wiele zmartwień.

Jeśli monitorujesz globalną tabelę atomów, zobaczysz, że aplikacje Delphi wyciekają z atomów, pozostawiając identyfikator Twojej aplikacji bez upuszczania go z pamięci:

Zobaczysz mnóstwo następujących elementów:

**Delphi000003B4*

*Controlofs0040000000009C0**

Zasadniczo, ponieważ nie możesz zarejestrować więcej niż 0xFFFF różnych identyfikatorów wiadomości windows, gdy tylko poprosisz o inny, system będzie return " Błąd systemu. Kod: 8. Nie ma wystarczającej ilości pamięci do przetworzenia tego polecenia ". Wtedy nie będzie można uruchomić żadnej aplikacji, która tworzy okno.

Kolejny problem został zgłoszony w Embarcadero QC Central.

Ten problem pojawia się pod Windows 7 / Windows Server 2008. Fakt, że na Windows Server 2003 i przed jego uruchomieniem jest spowodowany niewłaściwą implementacją, która recyklinguje Atomy, gdy ich indeks zawija się wokół maksimum 16384 jednostki.

Zapraszam do korzystania z mojego Global Atom Monitor aby sprawdzić, czy aplikacje Delphi przeciekają, czy nie.

Aby to naprawić, potrzebujesz łatki z Embarcadero.

 30
Author: Jordi Corbilla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-02 14:13:10

Szukam od 2 lat i dzięki Jordi Corbilla odpowiedz W końcu to mam!

W kilku słowach: źródło Delphi ma błędy, które powodują ten problem!

Let ' s understand what is going on:

Windows posiada obszar pamięci o nazwie "Atom table", który służy do komunikowania się aplikacji (Zobacz więcej ).

Również Windows ma inny "obszar pamięci", zwany "systemem wiadomości okien", który służy do tego samego celu (Zobacz więcej ).

Oba te obszary pamięci mają "16K slotów" każdy. W pierwszym z nich można usunąć atom, używając następującego interfejsu Windows API:

GlobalDeleteAtom // for removing an atom added by "GlobalAddAtom"

W drugim "obszarze", po prostunie możemy usunąć niczego!

Funkcja RegisterWindowMessage jest zwykle używana do rejestracji komunikaty do komunikacji między dwoma współpracującymi aplikacjami. Jeśli dwie różne aplikacje rejestrują ten sam ciąg wiadomości, aplikacje zwraca tę samą wartość wiadomości. wiadomość pozostaje rejestracja do zakończenia sesji .

Skompilowane Aplikacje Delphi (przynajmniej przez D7) umieszczają rekord w "obszarze wiadomości", a niektóre inne w "tabeli Atom" za każdym razem, gdy są uruchamiane. Aplikacja próbuje je usunąć, gdy aplikacja się zamyka, ale znalazłem wiele (i wiele) "przecieków atom", nawet po zamknięciu aplikacji.

W tym momencie możesz zobaczyć, że jeśli masz serwer, który uruchamia tysiące aplikacja dziennie, prawdopodobnie powinieneś wkrótce osiągnąć limit 16k i zaczyna się problem! Rozwiązanie w tym momencie? Tylko jeden restart.

Więc, co możemy zrobić? Cóż, mój przyjacielu, przykro mi to mówić, ale musimy naprawić kod źródłowy Delphi i przekompilować wszystkie aplikacje.

Najpierw otwórz elementy sterujące.pas i zastąp następujący wiersz:

RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));

Dla:

RM_GetObjectInstance := RegisterWindowMessage('RM_GetObjectInstance');

A następnie przekompiluj Pakiety Delphi i swoje aplikacje.

Jak znalazłem przecieki atomu nawet po zamknięciu aplikacji utworzyłem aplikację, która garbage zbiera każdy atom pozostawiony. Po prostu uruchamia następujący kod co godzinę:

procedure GarbageCollectAtoms;
var i, len : integer;
    cstrAtomName: array [0 .. 1024] of char;
    AtomName, Value, procName: string;
    ProcID,lastError : cardinal;
    countDelphiProcs, countActiveProcs, countRemovedProcs, countCantRemoveProcs, countUnknownProcs : integer;

    // gets program's name from process' handle
    function getProcessFileName(Handle: THandle): string;
    begin
      Result := '';
      { not used anymore
      try
        SetLength(Result, MAX_PATH);
        if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
          SetLength(Result, StrLen(PChar(Result)))
        else
          Result := '';
        except
      end;
      }
    end;

    // gets the last 8 digits from the given atomname and try to convert them to and integer
    function getProcessIdFromAtomName(name:string):cardinal;
    var l : integer;
    begin
      result := 0;
      l := Length(name);
      if (l > 8) then
      begin
        try
          result := StrToInt64('$' + copy(name,l-7,8));
          except
            // Ops! That should be an integer, but it's not!
            // So this was no created by a 'delphi' application and we must return 0, indicating that we could not obtain the process id from atom name.
            result := 0;
        end;
      end;
    end;

    // checks if the given procID is running
    // results: -1: we could not get information about the process, so we can't determine if is active or not
    //           0: the process is not active
    //           1: the process is active
    function isProcessIdActive(id: cardinal; var processName: string):integer;
    var Handle_ID: THandle;
    begin
      result := -1;
      try
        Handle_ID := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, id);
        if (Handle_ID = 0) then
        begin
          result := 0;
        end
        else
        begin
          result := 1;
          // get program's name
          processName := getProcessFileName(Handle_ID);
          CloseHandle(Handle_ID);
        end;
        except
          result := -1;
      end;
    end;

    procedure Log(msg:string);
    begin
      // Memo1.Lines.Add(msg);
    end;


begin

  // initialize the counters
  countDelphiProcs := 0;
  countActiveProcs := 0;
  countRemovedProcs := 0;
  countUnknownProcs := 0;

  // register some log
  Log('');
  Log('');
  Log('Searching Global Atom Table...');

  for i := $C000 to $FFFF do
  begin
    len := GlobalGetAtomName(i, cstrAtomName, 1024);
    if len > 0 then
    begin
      AtomName := StrPas(cstrAtomName);
      SetLength(AtomName, len);
      Value := AtomName;
      // if the atom was created by a 'delphi application', it should start with some of strings below
      if (pos('Delphi',Value) = 1) or
         (pos('ControlOfs',Value) = 1) or
         (pos('WndProcPtr',Value) = 1) or
         (pos('DlgInstancePtr',Value) = 1) then 
      begin
        // extract the process id that created the atom (the ProcID are the last 8 digits from atomname)
        ProcID := getProcessIdFromAtomName(value);
        if (ProcId > 0) then
        begin
          // that's a delphi process
          inc(countDelphiProcs);
          // register some log
          Log('');
          Log('AtomName: ' + value + ' - ProcID: ' + inttostr(ProcId) + ' - Atom Nº: ' + inttostr(i));
          case (isProcessIdActive(ProcID, procName)) of
            0: // process is not active
            begin
              // remove atom from atom table
              SetLastError(ERROR_SUCCESS);
              GlobalDeleteAtom(i);
              lastError := GetLastError();
              if lastError = ERROR_SUCCESS then
              begin
                // ok, the atom was removed with sucess
                inc(countRemovedProcs);
                // register some log
                Log('- LEAK! Atom was removed from Global Atom Table because ProcID is not active anymore!');
              end
              else
              begin
                // ops, the atom could not be removed
                inc(countCantRemoveProcs);
                // register some log
                Log('- Atom was not removed from Global Atom Table because function "GlobalDeleteAtom" has failed! Reason: ' + SysErrorMessage(lastError));
              end;
            end;
            1: // process is active
            begin
              inc(countActiveProcs);
              // register some log
              Log('- Process is active! Program: ' + procName);
            end;
            -1: // could not get information about process
            begin
              inc(countUnknownProcs);
              // register some log
              Log('- Could not get information about the process and the Atom will not be removed!');
            end;
          end;
        end;
      end;
    end;
  end;
  Log('');
  Log('Scan complete:');
  Log('- Delphi Processes: ' + IntTostr(countDelphiProcs) );
  Log('  - Active: ' + IntTostr(countActiveProcs) );
  Log('  - Removed: ' + IntTostr(countRemovedProcs) );
  Log('  - Not Removed: ' + IntTostr(countCantRemoveProcs) );
  Log('  - Unknown: ' + IntTostr(countUnknownProcs) );

  TotalAtomsRemovidos := TotalAtomsRemovidos + countRemovedProcs;

end;

(powyższy kod powstał na podstawie tego kodu )

Po tym, nigdy nie dostałem ten k * * błąd ponownie!

Późna Aktualizacja:

Również to jest źródło tego błędu: błąd aplikacji: adres błędu 0x00012afb

 21
Author: Christian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:39

Możesz użyć Desktop Heap Monitor firmy Microsoft, aby wyświetlić statystyki sterty (użyj % itd.) i jest dostępny pod adresem:

Http://www.microsoft.com/downloads/details.aspx?familyid=5cfc9b74-97aa-4510-b4b9-b2dc98c8ed8b&displaylang=en

 2
Author: HS1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-13 17:43:20

Zauważyłem ten błąd (Błąd systemu. Kod: 8. Za mało miejsca...) ostatnio, gdy używam jakiegoś kodu Twain, działo się to na moim komputerze, a nie na moim współpracowniku, a jedyną prawdziwą różnicą między naszymi maszynami jest to, że używam ekranu laptopa jako drugiego monitora, więc moje całkowite wymiary pulpitu są większe.

Znalazłem dokumentację problemu wskazanego powyżej przez Steve ' a Blacka, ale znalazłem sposób (który naprawił błąd na moim komputerze, przynajmniej), który nie wymaga edycji rejestr:

Stary kod używał

  DC := GetDC(Owner.VirtualWindow);
  // ...
  ReleaseDC(Owner.VirtualWindow, DC);

I okazało się, że zastąpienie go tym pozbyło się moich błędów

  DC := CreateCompatibleDC(Owner.VirtualWindow);
  // ...
  DeleteDC(DC);


Nie wiem, czy ma to związek z Twoim problemem, ale może być pomocne dla innych w przyszłości.

 2
Author: jasonpenny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-13 21:35:27

Mogą pojawić się błędy w kompilatorze, można się założyć, że to coś w Twojej aplikacji powoduje problem. Czy to możliwe, że Twoja aplikacja wycieka klamki okien lub jakiś inny obiekt GUI, taki jak długopisy / pędzle? To może być przyczyna.

 0
Author: Aikislave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-13 13:33:49

Dla mnie to było tylko kilka tjpegimages dekompresji w sposób pokaz slajdów, że w końcu zabrakło pamięci.

 0
Author: Anton Duzenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-25 11:50:04