Otrzymuję następujące ostrzeżenie:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace:
at EventEmitter.<anonymous> (events.js:139:15)
at EventEmitter.<anonymous> (node.js:385:29)
at Server.<anonymous> (server.js:20:17)
at Server.emit (events.js:70:17)
at HTTPParser.onIncoming (http.js:1514:12)
at HTTPParser.onHeadersComplete (http.js:102:31)
at Socket.ondata (http.js:1410:22)
at TCP.onread (net.js:354:27)
Napisałem taki kod w server.js:
http.createServer(
function (req, res) { ... }).listen(3013);
Jak to naprawić?
process.on('warning', e => console.warn(e.stack));
do debugowania ostrzeżenia. Nie używaj,process.setMaxListeners(0);
ponieważ ostrzeżenie jest z jakiegoś powodu.yarn install
. gdzie mogę umieścić tę linię, aby dodać śledzenie stosu?Odpowiedzi:
Jest to wyjaśnione w dokumentacji węzła eventEmitter
Co to za wersja Node? Jaki masz inny kod? To nie jest normalne zachowanie.
Krótko mówiąc:
process.setMaxListeners(0);
Zobacz także: node.js - żądanie - jak „emitter.setMaxListeners ()”?
źródło
process.on('uncaughtException', callback);
process.setMaxListeners(0); // OMG, its so simple... :D
Chciałbym tutaj podkreślić, że to ostrzeżenie jest nie bez powodu i istnieje duża szansa, że poprawka nie zwiększa limitu, ale zastanawia się, dlaczego dodajesz tak wielu słuchaczy do tego samego wydarzenia. Zwiększ limit tylko, jeśli wiesz, dlaczego dodaje się tak wielu słuchaczy i masz pewność, że naprawdę tego chcesz.
Znalazłem tę stronę, ponieważ dostałem to ostrzeżenie, aw moim przypadku wystąpił błąd w używanym przeze mnie kodzie, który zamieniał obiekt globalny w EventEmitter! Z pewnością odradzam globalne zwiększenie limitu, ponieważ nie chcesz, aby te rzeczy pozostały niezauważone.
źródło
Domyślnie dla każdego pojedynczego zdarzenia można zarejestrować maksymalnie 10 słuchaczy.
Jeśli to twój kod, możesz określić maxListeners poprzez:
Ale jeśli nie jest to Twój kod, możesz użyć tej sztuczki, aby globalnie zwiększyć domyślny limit:
Oczywiście możesz wyłączyć limity, ale bądź ostrożny:
BTW. Kod powinien znajdować się na samym początku aplikacji.
DODAJ: Od węzła 0.11 ten kod działa również w celu zmiany domyślnego limitu:
źródło
Przyjęta odpowiedź zawiera semantykę dotyczącą tego, jak zwiększyć limit, ale jak zauważył @voltrevo, ostrzeżenie istnieje z jakiegoś powodu i twój kod prawdopodobnie ma błąd.
Rozważ następujący kod błędu:
Teraz obserwuj poprawny sposób dodawania detektora:
Wyszukaj podobne problemy w kodzie przed zmianą maxListeners (co wyjaśniono w innych odpowiedziach)
źródło
Zastąpić
.on()
sięonce()
. Użycieonce()
usuwa detektory zdarzeń, gdy zdarzenie jest obsługiwane przez tę samą funkcję.Jeśli to nie rozwiąże problemu, zainstaluj ponownie Restler z tym w pakiecie.json „Restler”: „git: //github.com/danwrong/restler.git#9d455ff14c57ddbe263dbbcd0289d76413bfe07d”
Ma to związek z niewłaściwym zachowaniem Restlera 0.10 w węźle. problem można zobaczyć na git tutaj: https://github.com/danwrong/restler/issues/112 Jednak npm jeszcze tego nie zaktualizował, dlatego powinieneś odwołać się do głowy gita.
źródło
Otrzymuję to ostrzeżenie także podczas instalacji aglio na moim Mac OSX.
Używam cmd to naprawić.
https://github.com/npm/npm/issues/13806
źródło
Wersja węzła: v11.10.1
Komunikat ostrzegawczy ze śledzenia stosu:
Po wyszukaniu problemów z githubem, dokumentacji i utworzeniu podobnych przecieków pamięci emitera zdarzeń, ten problem został zaobserwowany ze względu na moduł węzła apn używany do powiadomień push iOS.
To rozwiązało:
Tworzyłem obiekt dostawcy za każdym razem, gdy wysyłano powiadomienie i oczekiwałem, że gc je usunie.
źródło
W moim przypadku wywołano go,
child.stderr.pipe(process.stderr)
gdy inicjowałem 10 (lub mniej więcej) przypadków dziecka. Wszystko, co prowadzi do dołączenia procedury obsługi zdarzeń do tego samego obiektu EventEmitter w pętli, powoduje, że nodejs zgłasza ten błąd.źródło
Czasami te ostrzeżenia pojawiają się, gdy nie jest to coś, co zrobiliśmy, ale coś, o czym zapomnieliśmy!
To ostrzeżenie napotkałem, gdy zainstalowałem pakiet dotenv z npm, ale został przerwany, zanim zacząłem dodawać instrukcję request ('dotenv'). Load () na początku mojej aplikacji. Gdy wróciłem do projektu, zacząłem otrzymywać ostrzeżenia „Wykryto przeciek pamięci potencjalnego zdarzenia”.
Zakładałem, że problem dotyczy czegoś, co zrobiłem, a nie czegoś, czego nie zrobiłem!
Po odkryciu przeoczenia i dodaniu instrukcji wymaganej ostrzeżenie o wycieku pamięci zniknęło.
źródło
Wolę wytropić i naprawić problemy, zamiast tłumić dzienniki, gdy tylko jest to możliwe. Po kilku dniach obserwowania tego problemu w mojej aplikacji, zdałem sobie sprawę, że ustawiam słuchaczy
req.socket
w oprogramowaniu pośrednim Express, aby wychwytywać błędy gniazd IO, które ciągle się pojawiały. W pewnym momencie dowiedziałem się, że nie jest to konieczne, ale i tak trzymałem słuchaczy w pobliżu. Właśnie je usunąłem, a występujący błąd zniknął. Zweryfikowałem, że to była przyczyna, uruchamiając żądania na mój serwer z następującym oprogramowaniem pośrednim i bez niego:Usunięcie tego oprogramowania pośredniego zatrzymało wyświetlane ostrzeżenie. Rozejrzę się dookoła twojego kodu i spróbuję znaleźć gdziekolwiek możesz skonfigurować słuchaczy, których nie potrzebujesz.
źródło
Miałem ten sam problem. problem został spowodowany, ponieważ słuchałem portu 8080 na 2 słuchaczach.
setMaxListeners()
działa dobrze, ale nie poleciłbym tego.poprawnym sposobem jest sprawdzenie kodu pod kątem dodatkowych detektorów, usunięcie detektora lub zmiana numeru portu, na którym nasłuchujesz, to naprawiło mój problem.
źródło
Miałem to do dziś, kiedy zaczynam
grunt watch
. Wreszcie rozwiązany przezIrytująca wiadomość zniknęła.
źródło
Musisz wyczyścić wszystkich detektorów przed utworzeniem nowych za pomocą:
Klient / Serwer
Zakładając, że gniazdo jest gniazdem klienta / lub utworzonym gniazdem serwera.
Możesz także zasubskrybować określone detektory zdarzeń, takie jak na przykład usunięcie
connect
detektora w następujący sposób:źródło
Powiedziałeś, że używasz
process.on('uncaughtException', callback);
Gdzie wykonujesz to oświadczenie? Czy jest to przekazane do wywołania zwrotnego
http.createServer
?Jeśli tak, inna kopia tego samego wywołania zwrotnego zostanie dołączona do zdarzenia uncaughtException przy każdym nowym żądaniu, ponieważ
function (req, res) { ... }
zostanie ona wykonana za każdym razem, gdy pojawi się nowe żądanie, podobnie jak instrukcjaprocess.on('uncaughtException', callback);
Zwróć uwagę, że obiekt procesu jest globalny dla wszystkich twoich żądań i dodania detektorów jego wydarzenie za każdym razem, gdy pojawi się nowe żądanie, nie będzie miało sensu. Możesz nie chcieć takiego zachowania.
Jeśli chcesz dołączyć nowego detektora do każdego nowego żądania, powinieneś usunąć wszystkich poprzednich detektorów dołączonych do zdarzenia, ponieważ nie będą już potrzebne przy użyciu:
process.removeAllListeners('uncaughtException');
źródło
Rozwiązaniem naszego zespołu było usunięcie ścieżki rejestru z naszego pliku .npmrc. W pliku rc mieliśmy dwa aliasy ścieżek, a jeden wskazywał na przestarzałą instancję Artifactory.
Błąd nie miał nic wspólnego z rzeczywistym kodem naszej aplikacji, ale wszystko, co dotyczy naszego środowiska programistycznego.
źródło
Miałem do czynienia z tym samym problemem, ale z powodzeniem poradziłem sobie z asynchronicznym oczekiwaniem.
Sprawdź, czy to pomaga.
niech dataLength = 25;
Przed:
for (niech i = 0; i <dataLength; i ++) {
sftp.get (remotePath, fs.createWriteStream (
xyzProject/${data[i].name}
));}
Po:
for (niech i = 0; i <dataLength; i ++) {
czekaj na sftp.get (remotePath, fs.createWriteStream (
xyzProject/${data[i].name}
));}
źródło
Dzięki RLaaa za pomysł, jak rozwiązać prawdziwy problem / podstawową przyczynę ostrzeżenia. W moim przypadku był to kod buggy MySQL.
Pod warunkiem, że napisałeś obietnicę z kodem wewnątrz:
Zauważ, że
conn.on('error')
w kodzie jest detektor. Ten kod dosłownie dodający detektor w kółko zależy od tego, ile razy wywołujesz zapytanie. Tymczasemif(err) reject(err)
robi to samo.Więc usunąłem
conn.on('error')
słuchacza i voila ... rozwiązane! Mam nadzieję, że to ci pomoże.źródło
Umieść to w pierwszym wierszu pliku server.js (lub cokolwiek, co zawiera główną aplikację Node.js):
require('events').EventEmitter.prototype._maxListeners = 0;
i błąd znika :)
źródło