Chcę poznać rozmiar zajmowany przez obiekt JavaScript.
Weź następującą funkcję:
function Marks(){
this.maxMarks = 100;
}
function Student(){
this.firstName = "firstName";
this.lastName = "lastName";
this.marks = new Marks();
}
Teraz tworzę instancję student
:
var stud = new Student();
żebym mógł robić takie rzeczy jak
stud.firstName = "new Firstname";
alert(stud.firstName);
stud.marks.maxMarks = 200;
itp.
Teraz stud
obiekt zajmie pewien rozmiar w pamięci. Ma trochę danych i więcej obiektów.
Jak dowiedzieć się, ile pamięci stud
zajmuje obiekt? Coś jak sizeof()
w JavaScript? Byłoby naprawdę niesamowite, gdybym mógł to znaleźć w jednym wywołaniu funkcji, takim jak sizeof(stud)
.
Przeszukuję Internet od miesięcy - nie mogłem go znaleźć (zadane na kilku forach - brak odpowiedzi).
javascript
memory
object
sizeof
użytkownik4642212
źródło
źródło
Odpowiedzi:
Ponownie rozważyłem kod w mojej oryginalnej odpowiedzi . Usunąłem rekursję i usunąłem przypuszczalne istnienie.
źródło
"よんもじ".length
ma 4 w JavaScript, ale czy jesteś pewien, że ma 8 bajtów, ponieważ kod go zwraca?var a={n:1}; var b={a:function(){return a}}; roughSizeOfObject(b)
- tutajb
znajduje się odniesienie doa
, aleroughSizeOfObject()
zwraca0
.Google Chrome Heap Profiler umożliwia sprawdzenie wykorzystania pamięci obiektów.
Musisz być w stanie zlokalizować obiekt w śladzie, co może być trudne. Po przypięciu obiektu do globalnego okna można go łatwo znaleźć w trybie listy „Ograniczenie”.
Na załączonym zrzucie ekranu utworzyłem w oknie obiekt o nazwie „testObj”. Następnie zlokalizowałem w profilerze (po nagraniu) i pokazuje pełny rozmiar obiektu i wszystkiego w nim pod „zachowanym rozmiarem”.
Więcej informacji na temat awarii pamięci .
Na powyższym zrzucie ekranu obiekt ma zachowany rozmiar 60. Myślę, że jednostka jest tutaj bajtami.
źródło
comparison
widok na dole. Widać, jakie obiekty zostały utworzone między dwoma migawkami.Shallow size
wydaje się 40 dla obu{ a:"55c2067aee27593c03b7acbe", b:"55c2067aee27593c03b7acbe", c:null, d:undefined }
i{ c:null, d:undefined }
obiektów. Czy to jest w porządku?node --inspect
iw przeglądarce Chrome wpiszabout:inspect
na pasku adresu URL i poszukaj otwarcia Inspektora węzłów. Utwórz obiekt w węźle CLI, a następnie zrób migawkę sterty.Właśnie to napisałem, aby rozwiązać podobny (ish) problem. Nie robi dokładnie tego, czego możesz potrzebować, tzn. Nie bierze pod uwagę sposobu, w jaki interpreter przechowuje obiekt.
Ale jeśli używasz wersji V8, powinno to dać ci całkiem przybliżone przybliżenie, ponieważ niesamowite prototypowanie i ukryte klasy pochłaniają większość kosztów ogólnych.
źródło
Czasami używam tego do oznaczania naprawdę dużych obiektów, które mogą trafiać do klienta z serwera. Nie reprezentuje miejsca w pamięci. To po prostu przybliża Cię do kosztu wysłania lub przechowywania.
Pamiętaj też, że jest powolny, tylko deweloper. Ale dla uzyskania odpowiedzi na pytanie z jednym wierszem kodu było to dla mnie przydatne.
źródło
VM1409:1 Uncaught TypeError: Converting circular structure to JSON
:( nadal jest przydatnaOto nieco bardziej kompaktowe rozwiązanie problemu:
źródło
typeof ...
razie nie działałyby.Istnieje moduł NPM, aby uzyskać rozmiar obiektu , można go zainstalować za pomocą
npm install object-sizeof
źródło
Jest to hacky sposób, ale próbowałem go dwa razy z różnymi liczbami i wydaje się być spójny.
Możesz spróbować przydzielić ogromną liczbę obiektów, na przykład jeden lub dwa miliony obiektów, które chcesz. Umieść obiekty w tablicy, aby zapobiec ich zwolnieniu przez moduł wyrzucania elementów bezużytecznych (pamiętaj, że spowoduje to niewielki narzut pamięci z powodu tablicy, ale mam nadzieję, że nie powinno to mieć znaczenia, a poza tym, jeśli będziesz się martwić, że obiekty będą w pamięci , gdzieś je przechowujesz). Dodaj alert przed i po alokacji, aw każdym alercie sprawdź, ile pamięci zajmuje proces Firefox. Przed otwarciem strony z testem upewnij się, że masz nową instancję przeglądarki Firefox. Otwórz stronę, zwróć uwagę na użycie pamięci po wyświetleniu ostrzeżenia „przed”. Zamknij alert, poczekaj na przydzielenie pamięci. Odejmij nową pamięć od starszej i podziel ją przez liczbę przydziałów.
Próbowałem tego na swoim komputerze, a proces miał 48352 KB pamięci, gdy pojawił się alert „przed”. Po alokacji Firefox miał 440236 KB pamięci. Dla 2 milionów alokacji jest to około 200 bajtów na każdy obiekt.
Próbowałem jeszcze raz z alokacją 1 miliona i wynik był podobny: 196 bajtów na obiekt (przypuszczam, że dodatkowe dane w 2 mill zostały użyte dla Array).
Oto hacky sposób, który może ci pomóc. JavaScript nie zapewnia powodu „sizeof” z jakiegoś powodu: każda implementacja JavaScript jest inna. Na przykład w Google Chrome ta sama strona zużywa około 66 bajtów na każdy obiekt (przynajmniej na podstawie menedżera zadań).
źródło
Przepraszam, że nie mogłem skomentować, więc kontynuuję pracę od tomwrong. Ta ulepszona wersja nie będzie liczyć obiektu więcej niż jeden raz, dlatego nie będzie nieskończonej pętli. Ponadto uważam, że klucz obiektu powinien być mniej więcej liczony.
źródło
typeof value === 'object'
to za mało i będziesz mieć wyjątki, jeśli wartość tonull
.level
zawiera dane, aleroughSizeOfObject(level)
zwraca zero. (Oczywiście, mojego poziomu zmiennych nie należy mylić z twoim argumentem. Nie sądzę, że cieniowanie zmiennych powinno powodować tutaj problem, a także kiedy zmieniam nazwę „poziomu” w twoim skrypcie, otrzymuję ten sam wynik.) Zrzut ekranu : snipboard.io/G7E5yj.jpgMając ten sam problem. Szukałem w Google i chcę podzielić się tym rozwiązaniem ze społecznością Stackoverflow.
Ważne :
Co o tym myślisz?
źródło
Kontynuując ten komentarz, oto, co powinieneś zrobić: Spróbuj wywołać problem z pamięcią - Napisz kod, który tworzy wszystkie te obiekty i poważnie zwiększ górny limit, dopóki nie napotkasz problemu (awaria przeglądarki, zawieszenie przeglądarki lub błąd Out-Of- błąd pamięci). Idealnie powinieneś powtórzyć ten eksperyment z różnymi przeglądarkami i innym systemem operacyjnym.
Teraz są dwie opcje: opcja 1 - Nie udało się stworzyć problemu z pamięcią. Dlatego martwisz się o nic. Nie masz problemu z pamięcią, a twój program jest w porządku.
opcja 2 - masz problem z pamięcią. Teraz zadaj sobie pytanie, czy limit, na którym wystąpił problem, jest rozsądny (innymi słowy: czy jest prawdopodobne, że ta liczba obiektów zostanie utworzona przy normalnym użyciu twojego kodu). Jeśli odpowiedź brzmi „nie”, to nic ci nie jest. W przeciwnym razie wiesz już, ile obiektów może utworzyć Twój kod. Przerób algorytm tak, aby nie przekroczył tego limitu.
źródło
Jeśli Twoim głównym problemem jest wykorzystanie pamięci przez rozszerzenie Firefoksa, sugeruję sprawdzenie u programistów Mozilli.
Mozilla udostępnia na swojej wiki listę narzędzi do analizy wycieków pamięci .
źródło
Ta biblioteka JavaScript
sizeof.js
robi to samo. Uwzględnij to w ten sposóbFunkcja sizeof przyjmuje obiekt jako parametr i zwraca jego przybliżony rozmiar w bajtach. Na przykład:
Funkcja sizeof może obsługiwać obiekty, które zawierają wiele odniesień do innych obiektów i odwołania rekurencyjne.
Pierwotnie opublikowane tutaj .
źródło
Narzędzia dla programistów Chrome mają tę funkcję. Uważam, że ten artykuł jest bardzo pomocny i robi dokładnie to, co chcesz: https://developers.google.com/chrome-developer-tools/docs/heap-profiling
źródło
Ogromne podziękowania dla wszystkich, którzy pracowali nad tym kodem!
Chciałem tylko dodać, że szukałem dokładnie tego samego, ale w moim przypadku jest to zarządzanie pamięcią podręczną przetworzonych obiektów, aby uniknąć konieczności ponownego analizowania i przetwarzania obiektów z wywołań ajax, które mogły być buforowane lub nie przez przeglądarkę. Jest to szczególnie przydatne w przypadku obiektów wymagających dużego przetwarzania, zwykle wszystkiego, co nie jest w formacie JSON, ale utrzymanie tych danych w pamięci podręcznej w dużym projekcie lub aplikacji / rozszerzeniu, które pozostają uruchomione przez długi czas, może być bardzo kosztowne. czas.
W każdym razie używam go do czegoś takiego jak:
Jest to uproszczony przykład i może zawierać pewne błędy, ale daje pomysł, ponieważ można go użyć do trzymania obiektów statycznych (zawartość się nie zmieni) z pewnym stopniem inteligencji. Może to znacznie ograniczyć wszelkie kosztowne wymagania przetwarzania, które obiekt musiałby być wyprodukowany w pierwszej kolejności.
źródło
źródło
Korzystam z karty Oś czasowa narzędzi deweloperskich Chrome , tworzę instancje coraz większej liczby obiektów i uzyskuję takie dobre oszacowania. Możesz użyć html takiego jak ten poniżej, jako bojlera, i zmodyfikować go, aby lepiej symulować cechy twoich obiektów (liczbę i typy właściwości itp.). Możesz kliknąć ikonę kosza na śmieci na dole tej karty narzędzi programistycznych, przed i po uruchomieniu.
Utworzenie wystąpienia 2 milionów obiektów o tylko jednej właściwości (tak jak w powyższym kodzie powyżej) prowadzi obecnie do przybliżonego obliczenia 50 bajtów na obiekt na moim Chromium. Zmiana kodu w celu utworzenia losowego ciągu na obiekt dodaje około 30 bajtów na obiekt itp. Mam nadzieję, że to pomaga.
źródło
Jeśli musisz programowo sprawdzić aprox. rozmiar obiektów można również sprawdzić w tej bibliotece http://code.stephenmorley.org/javascript/finding-the-memory-usage-of-objects/ , którego byłem w stanie użyć do określania wielkości obiektów.
W przeciwnym razie proponuję użyć przeglądarki stosu Chrome / Firefox.
źródło
Myślę, że zapomniałeś dołączyć „tablicę”.
źródło
Ja wiem to nie jest absolutnie dobry sposób, żeby to zrobić, jeszcze it've pomógł mi kilka razy w przeszłości, aby uzyskać rozmiar pliku ok obiektu:
Napisz swój obiekt / odpowiedź do konsoli lub nowej karty, skopiuj wyniki do nowego pliku notatnika, zapisz go i sprawdź rozmiar pliku. Sam plik notatnika ma zaledwie kilka bajtów, dzięki czemu uzyskasz dość dokładny rozmiar pliku obiektu.
źródło