CodeGym /בלוג Java /Random-HE /עוד על אספן האשפה
John Squirrels
רָמָה
San Francisco

עוד על אספן האשפה

פורסם בקבוצה
היי! בשיעור האחרון התוודענו לראשונה לאספן האשפה המובנה של ג'אווה וקיבלנו מושג גס איך הוא עובד. זה עובד ברקע בזמן שהתוכנית שלך פועלת, אוסף אובייקטים מיותרים שיימחקו מאוחר יותר. כך, הוא מפנה זיכרון שניתן להשתמש בו כדי ליצור אובייקטים חדשים בעתיד.
עוד על אספן האשפה - 1
בשיעור זה, נדון בפירוט רב יותר כיצד זה עובד. למשל, איך ומתי חפץ הופך למיותר? ואיך מגלה אספן האשפה? אלו שאלות שנענה עליהן במהלך השיעור של היום :) השיעור יהיה יותר כמו סקירה כללית: אין צורך ללמוד את החומר הזה בעל פה. הכוונה היא בעיקר להרחיב את החזון שלכם לגבי אופן פעולת הזיכרון והאספן, אז פשוט תקראו ותמצאו לעצמכם משהו חדש :) בואו נצא! הדבר הראשון שאתה צריך לזכור הוא שאוסף האשפה פועל במקביל לתוכנית שלך . זה לא חלק מהתוכנית שלך. הוא פועל בנפרד (בשיעור האחרון השווינו את זה לשואב אבק רובוטי) אבל זה לא תמיד היה כך. פעם איסוף אשפה התבצע באותו שרשור כמו התוכנית שלך. בלוח זמנים כלשהו (אחת לכמה דקות), אספן האשפה היה בודק נוכחותם של אובייקטים לא רצויים בתוכנית. הבעיה הייתה שהתוכנית נתקעה (לא תבוצע) במהלך הבדיקה ואיסוף האשפה. תאר לעצמך שאתה יושב במשרד שלך בעבודה. אבל אז נכנסת המנקה לשטוף את הרצפות. היא מרחיקה אותך מהמחשב שלך למשך 5 דקות ואתה מחכה עד שהיא תסיים לנקות. במהלך תקופה זו, אינך יכול לעבוד. זה בערך איך עבד איסוף האשפה :) מנגנון זה שונה מאוחר יותר, ועכשיו אוסף האשפה פועל ברקע, ולא מפריע לעבודה של התוכנית עצמה. אתה כבר יודע שאובייקט מת כשאין לו עוד הפניות. במציאות, אספן האשפה לא סופר הפניות לאובייקטים . ראשית, זה יכול לקחת הרבה זמן. שנית, זה לא מאוד יעיל. אחרי הכל, חפצים יכולים להתייחס זה לזה! עוד על אספן האשפה - 2האיור מציג דוגמה שבה 3 אובייקטים מתייחסים זה לזה, אך אף אחד אחר לא מתייחס אליהם. במילים אחרות, שאר התוכנית לא צריך אותם. אם אספן האשפה פשוט סופר הפניות, 3 החפצים הללו לא היו נאספים והזיכרון לא היה משתחרר (יש אליהם הפניות!). אנחנו יכולים להשוות את זה לחללית. במהלך הטיסה, האסטרונאוטים מחליטים לבדוק את רשימת חלקי החילוף הזמינים לתיקונים. בין היתר הם מוצאים הגה ודוושות ממכונית רגילה. ברור שהם לא נחוצים כאן והם תופסים מקום שלא לצורך (אם כי שני החלקים האלה קשורים זה לזה ויש להם כמה פונקציות). אבל בתוך החללית, הם זבל חסר תועלת שיש להשליך. בהתאם לכך, בג'אווה התקבלה ההחלטה לאסוף אשפה על סמך ספירת הפניות, אלא על הפרדה של אובייקטים לשני סוגים: נגיש ובלתי ניתן להשגה. כיצד אנו קובעים אם ניתן להגיע לאובייקט? הכל פשוט גאוני. ניתן להגיע לאובייקט אם מפנה אליו אובייקט אחר שניתן להגיע אליו. כך, אנו מקבלים "שרשרת של נגישות". זה מתחיל עם תחילת התוכנית וממשיך למשך כל התוכנית. זה נראה בערך כך: עוד על אוסף האשפה - 3 החץ באיור מציין את קוד ההפעלה של התוכנית שלנו. הקוד (לדוגמה, main()השיטה) יוצר הפניות לאובייקטים. אובייקטים אלה יכולים להתייחס לאובייקטים אחרים, אובייקטים אלה לאובייקטים אחרים, וכן הלאה. זה יוצר שרשרת התייחסות . אם אתה יכול להתחקות לאורך לשרשרת מאובייקט ל"הפניה לשורש" (זה שנוצר ישירות בקוד ההפעלה), אז זה נחשב לנגיש. חפצים כאלה מסומנים בשחור בתמונה. אבל לא ניתן להגיע לאובייקט אם האובייקט נושר משרשרת זו, כלומר אף אחד מהמשתנים בקוד שמבוצע כעת לא מתייחס אליו, ולא ניתן להגיע אליו דרך "שרשרת ההתייחסות". בתוכנית שלנו, שני אובייקטים כאלה מסומנים באדום. שימו לב שלאובייקטים ה"אדומים" הללו יש הפניות זה לזה. אבל כפי שאמרנו קודם, אספן האשפה המודרני של ג'אווה לא סופר הפניות. הוא קובע אם ניתן להגיע לאובייקט או לא ניתן להגיע אליו . כתוצאה מכך, הוא יתפוס את שני העצמים האדומים באיור. עכשיו בואו נסתכל על כל התהליך מתחילתו ועד סופו. תוך כדי כך, נראה גם כיצד הזיכרון מסודר ב-Java :) כל אובייקטי Java מאוחסנים באזור מיוחד של זיכרון הנקרא heap . בשפת היומיום, ערימה היא בדרך כלל הר של פריטים, שבו הכל מעורבב. אבל זה לא מה שהערימה בג'אווה. המבנה שלו מאוד הגיוני והגיוני. בשלב מסוים, מתכנתי Java גילו שניתן לחלק את כל האובייקטים שלהם לשני סוגים: אובייקטים פשוטים ו"אובייקטים ארוכים" . "חפצים ארוכים" הם חפצים ששרדו סבבים רבים של איסוף אשפה. בדרך כלל הם חיים עד שהתוכנית מסתיימת. בסופו של דבר, הערימה המלאה, שבה מאוחסנים כל החפצים, חולקה לכמה חלקים. לחלק הראשון יש שם יפה: עדן(מתוך "גן העדן" המקראי). השם הזה מתאים, כי זה המקום שבו אובייקטים מגיעים לאחר יצירתם. זהו החלק בזיכרון שבו נוצרים אובייקטים חדשים כאשר אנו משתמשים במילת המפתח חדש. עשויים להיווצר הרבה אובייקטים. כאשר לאזור הזה נגמר המקום, מתחיל איסוף אשפה "מהיר" ראשוני. אנחנו חייבים לומר כי אספן האשפה הוא מאוד חכם. הוא בוחר באלגוריתם על סמך האם בערימה יש יותר אשפה או יותר חפצים חיים. אם כמעט כל החפצים הם זבל, האספן מסמן את החפצים החיים ומעביר אותם לאזור אחר של זיכרון. ואז האזור הנוכחי מנוקה לחלוטין. אם אין הרבה אשפה, והערימה היא בעיקר חפצים חיים, האספן מסמן את האשפה, מפנה אותה ואורז את שאר החפצים יחד. אמרנו "האספן מסמן את החפצים החיים ומעביר אותם לאזור אחר של זיכרון", אבל איפה? אזור זיכרון שבו כל החפצים ששרדו לפחות סיבוב אחד של איסוף אשפה מועברים נקרא מרחב הישרדות . מרחב הישרדות , בתורו, מחולק לדורות . כל חפץ שייך לדור מסוים, תלוי בכמה סבבים של איסוף אשפה הוא שרד. אם חפץ שרד סיבוב אחד של איסוף אשפה, אז הוא ב"דור 1"; אם 5, אז "דור 5". יחד, עדן ומרחב הישרדות יוצרים אזור שנקרא הדור הצעיר . בנוסף לדור הצעיר, יש לערימה אזור זיכרון נוסף שנקרא הדור הישן . זה בדיוק האזור שבו מגיעים חפצים ארוכי חיים ששרדו סבבים רבים של איסוף אשפה. יש יתרונות בשמירה עליהם בנפרד מכל האחרים. איסוף אשפה מלא מתבצע רק כאשר הדור הישן מלא, כלומר יש כל כך הרבה חפצים ארוכים בתוכנית שאין מספיק זיכרון. תהליך זה כולל יותר מאזור אחד בזיכרון. באופן כללי, זה כולל את כל האובייקטים שנוצרו על ידי מכונת Java. מטבע הדברים, זה לוקח הרבה יותר זמן ומשאבים. זו בדיוק ההחלטה שהתקבלה לאחסן חפצים ארוכים בנפרד. "איסוף אשפה מהיר" מתבצע כאשר לאזורים אחרים נגמר המקום. זה כרוך רק בתחום אחד, מה שהופך אותו למהיר ויעיל יותר. לבסוף, כאשר אפילו השטח עבור חפצים ארוכים מתמלא לחלוטין, איסוף אשפה מלא מופעל. כך, האספן משתמש בכלי ה"כבד" רק כאשר אי אפשר להתחמק ממנו. הנה ייצוג חזותי של מבנה הערימה ואיסוף האשפה: עוד על אוסף האשפה - 4
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION