איסוף זבל על משתנה שלכודה ב-closure ב-JS/V8 - שאלה
-
אתמול התעוררתי לגבי שאלה זו, ואולי התשובה תעזור לבעיית @מנצפך כאן.
נגיד שיש לנו קוד כזה:
function () { let a = {}; setInterval(() => {}, 1000) }
מתי אובייקט
a
הולך לפח הזבל?
צדדי השאלה:- מצד אחד, אחרי שאף אחד לא ישתמש באובייקט הזה אחרי הרצת הפונקציה, ניתן לזרוק אותו לפח מיד בסוף הפונקציה.
- מצד שני, זה חוקי לפונקציה האנונימית שהעברתי ל-
setInterval
לגשת אלa
, ובשפה אחרתa
נמצאת עכשיו בתוך closure.
האם אוסף הזבל של V8 מספיק חכם לדעת שהפונקציה לא הולכת להשתמש במשתנה או לא?
-
@מנצפך ראיתי עכשיו תשובה זו (ועוד כמה: [1], [2]) שטוענות שהוא לא יישאר בזכרון אם המנוע מצליח לזהות שהוא לא בשימוש על ידי הפונקציה הפנימית.
עריכה: הוא לא יישאר בזכרון אם המנוע מצליח לזהות שהוא לא בשימוש על ידי אף אחד מהפונקצי
הות הפנימיותעיין כאן: https://stackoverflow.com/questions/19798803
@מנצפך האם בדקת שזה לא מה שגורם לניפוח הזיכרון בתוכנה שלך?
-
@yossiz לגבי המקרה שלי, אני לא מאמין שיש שם באמת memory leak
כי אם כך כל הזמן הזיכרון היה מתנפח.
אצלי זה קורה מידי פעם (בשעות עומס כמובן). וההתנהגות היא של קפיצה בזיכרון ואז שחרור למצב רגיל. מה שמוביל אותי למסקנה שזה פשוט ה - GC שלוקח לו זמן להיכנס לפעולה (הוא הרי לא עובד כל הזמן).אני מנסה לפתור את זה בדרכים חלופיות, ע"י חלוקת עומסים.
למעשה, הספק מנקר בי כל הזמן האם זה בעית הזיכרון מצויה ב NodeJS יותר מאשר בשפה אחרת. בוודאי שצריך למצוא את הספריות הנכונות לעבוד איתן.
-
לגבי מה שכתבת,
בפונקציה שאני חושד בה בעיקר, יש גישה לDB עם await
שזה בעצם יוצר פונקציה פנימית. אבל אין שום גישה לאף קוד חיצוני לפונקציה הזו.אני מסתפק האם יש להציב בסוף הפוקנציה null לכל המערכים שאיתם עבדתי.
בכל מקרה אני מצהיר על המערכים עם let. זה אומר שהם בוודאי לא זמינים החוצה.
ייתכן של GC יותר מובן אם אני מציב null?
אבדוק את זה.