Java Integer Pool (Integer Cache)
ב-Java קיימים שני אזורי זיכרון עיקריים:
📚 Stack (מחסנית)
- שומר משתנים מקומיים.
- שומר רפרנסים (כתובות) לאובייקטים.
- מהיר מאוד לגישה.
🗄 Heap (ערימה)
- שומר אובייקטים.
- שומר מערכים (Arrays).
- כל אובייקט שנוצר באמצעות
newנשמר בו.
אז מה בעצם קורה בזיכרון כאשר אנחנו יוצרים משתנה מסוג Integer?
Integer x = 10;
- נוצר אובייקט Integer ב-Heap.
- המשתנה x נשמר ב-Stack.
- x מחזיק רפרנס לאובייקט שנמצא ב-Heap.
Integer a = new Integer(5);
- נוצר אובייקט חדש ב-Heap.
- המשתנה a מחזיק רפרנס אליו.
🔍 השוואת Integer
כאשר רוצים להשוות ערכים של Integer, בדרך כלל נשתמש ב-equals:
Integer x = 200;
Integer y = 200;
System.out.println(x.equals(y));
פלט: true
הסיבה היא ש-equals משווה את הערך עצמו ולא את מיקום האובייקט בזיכרון.
עכשיו ננסה להשתמש ב-== :
Integer x = 200;
Integer y = 200;
System.out.println(x == y);
פלט: false
הסיבה היא שהאופרטור == משווה רפרנסים ולא ערכים.
אבל מה יקרה אם נשתמש בערך 100?
Integer x = 100;
Integer y = 100;
System.out.println(x == y);
פלט: true
רגע... למה הפעם קיבלנו true?
🚀 הכירו את Integer Cache
Java מכילה מנגנון אופטימיזציה בשם Integer Cache (או Integer Pool).
עבור ערכים בטווח:
-128 עד 127Java שומרת אובייקטים מוכנים מראש וממחזרת אותם במקום ליצור אובייקטים חדשים.
Integer x = 100;
Integer y = 100;
במקרה זה שני המשתנים מצביעים לאותו אובייקט בזיכרון ולכן:
x == yמחזיר true.
❌ מה קורה מחוץ לטווח?
Integer x = 200;
Integer y = 200;
הערך 200 נמצא מחוץ לטווח ה-Cache ולכן נוצרים שני אובייקטים שונים.
כתוצאה מכך:
x == yמחזיר false.
💡 למה Java עושה את זה?
- חיסכון בזיכרון.
- פחות יצירת אובייקטים.
- ביצועים טובים יותר.
- פחות עומס על ה-Garbage Collector.
בתקופה שבה זיכרון היה משאב יקר, המנגנון הזה סיפק שיפור משמעותי בביצועים ובצריכת הזיכרון.
⚙️ הקשר ל-Autoboxing
כאשר Java ממירה אוטומטית מ-int ל-Integer:
Integer x = 100;
מאחורי הקלעים Java מבצעת פעולה דומה ל:
Integer x = Integer.valueOf(100);
המתודה valueOf בודקת האם הערך קיים ב-Cache ומחזירה אובייקט קיים במידת האפשר.
🏗 איפה המנגנון ממומש?
המנגנון ממומש בתוך המחלקה:
java.lang.Integerבעת טעינת המחלקה נוצר מערך Cache פנימי המכיל את הערכים בטווח הנתמך.
🔧 האם ניתן לשנות את הטווח?
התשובה היא כן ולא.
- הגבול התחתון (128-) קבוע ואינו ניתן לשינוי.
- הגבול העליון (127) ניתן להגדלה.
באמצעות הפרמטר:
-XX:AutoBoxCacheMax=1000Java תשמור Cache עבור ערכים בטווח:
min:-128 max:1000🎯 סיכום
כאשר משווים Integer-ים, מומלץ להשתמש ב-equals ולא ב-==.
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false
System.out.println(c.equals(d)); // true
Integer Cache הוא אחד מאותם מנגנונים קטנים ב-Java שמזכירים לנו שלא תמיד מה שאנחנו רואים בקוד הוא כל הסיפור. לפעמים יש לא מעט קסם שמתרחש מאחורי הקלעים.