2014-12-05 57 views
1

我有一個25MB的json文件,我「需要」爲什麼我的應用程序啓動。初看起來,node.js進程似乎佔用了將近200MB的內存。爲什麼node.js突然使用更少的內存?

但是如果我讓它運行並回到它,活動監視器報告它只使用了9MB,這根本沒有意義!至少,它應該是更多MB,因爲即使是一個簡單的node.js應用程序幾乎不做任何事(就像服務器一樣),使用9MB。

該應用程序似乎工作正常 - 它是一個服務器,提供搜索建議形成一個220,000字的單詞列表。

活動監視器是否錯誤? 爲什麼它只使用9MB,但最初在應用程序啓動時使用〜200MB?

+5

因爲它做的東西使用了大量的內存,那麼該內存得到GCed? – 2014-12-05 15:38:38

+0

它最初將使用內存卡來加載程序並進行編譯,一旦完成,它將清除相當一部分內存。懷疑這將佔據200mb的頭腦。 – DoctorMick 2014-12-05 15:39:20

+2

加載一個25mb的字符串並處理它會花費很多,但是一旦發生這種情況,解析25mb json所需的所有內存都可以被收集,只剩下一個(精簡的)內存結構。 – spender 2014-12-05 15:41:33

回答

1

由於是JavaScript,不再使用的東西通過垃圾收集器(GC)被移除,釋放內存。一切(或許多事情)在開始時可能已經加載到內存中。然後不再需要的項目被GC從內存中移除。通常情況下,生成過程可能會佔用更多內存,之後會丟失一些內存,例如臨時數據結構可能正在使用中,但在完成此過程時不再需要。

這也可能是內存中的項目暫時交換出來並寫入磁盤(可能稍後會檢索),這種交換是由您的操作系統完成的,並且傾向於更多地用於保留大量內存的程序。

0

加載文件需要多少內存取決於許多因素

正在使用什麼文本編碼來存儲文件? JavaScript在內部使用UTF-16,因此如果這不是磁盤上使用的內容,則大小可能不同。例如,如果文件採用UTF-32格式,那麼內存中的UTF-16版本將會變小,除非它充滿了星體。如果文件使用UTF-8格式,則情況會相反:內存版本將更大,除非它充滿了星體。但現在,讓我們假設它們的大小差不多,或者是因爲它們使用了相同的編碼,或者是星際模式恰好使文件大小差不多相同。

你說得對,加載文件需要至少25MB(假設編碼不會干擾)。 JSON API的語義就是它們,你需要將整個文件作爲一個字符串存儲在內存中,所以當時應用程序至少佔用了那麼多內存。這不會計算解析器需要運行的任何內容,所以您至少需要34MB:25的文件,9的Node,然後無論您的特定應用程序用於自己。

但是你的應用並不需要所有的內存。根據你編寫應用程序的方式,你可能在某些時候摧毀了你對文件的引用。 由於JSON的語義,沒有辦法避免將整個文件加載到內存中,這需要25MB,因爲這是文件的大小。也無法避免佔用JSON解析器完成工作和構建對象所需的任何內存。

但是,根據您編寫應用程序的方式,當您不再需要該數據時,可能會出現一個問題。您可以退出您用於加載文件的函數,也可以將該變量分配給其他項或其他任何可能的項。然而,它發生,JavaScript回收不再使用的內存。這被稱爲垃圾回收,它在所謂的「腳本語言」中很受歡迎(儘管其他編程語言也可以使用它)。

還有文字表示與內存表示的問題。除非您更改編碼,否則字符串需要的內存空間與磁盤空間相同,但Numbers和Booleans完全是另一回事。在JavaScript中,所有Numbers都是64位浮點數,所以如果磁盤上的大部分數字長度超過四個字符,則內存中的表示將會更小,可能會相當多。請注意,我說的是字符,而不是數字:數字是字符,但是+, - ,e和。也是字符,因此-1e0在寫爲文本時佔用的空間是-1的兩倍,儘管它們在內存中表示相同的值。作爲另一個例子,3.14佔用與文本1000一樣多的空間(並且恰好佔用相同數量的內存空間:每個64位)。但-0.00000001和100000000佔用的內存空間比磁盤少得多,因爲內存中的表示更小。布爾變得更小:不同的引擎以不同的方式存儲它們,但是理論上你可以在一個小時內完成它。這與存儲「真」所需的8個字節或存儲「假」的10個字節相差甚遠。

因此,如果您的數據主要是關於Numbers和Booleans,那麼內存中的表示會變得更小。如果它主要是絃樂,那麼不是那麼多。

相關問題