JavaRush /בלוג Java /Random-HE /עוד על אוסף האשפה בג'אווה

עוד על אוסף האשפה בג'אווה

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