«

»

Dec 16

מבנה הזיכרון ב Java

מבנה הזיכרון ב Java 

 
 

רקע תאורטי:

 

הנושא של זיכרון הוא רחב מאוד, במאמר זה לא ארחיב על ה Heap ועל ה Stack אלא רק אפרט על כמות הזיכרון שלוקחים משתנים פרימיטיביים ואובייקטים.

בסוף המאמר תוכלו לחשב ולהגיע למסקנות לגבי תפיסת הזיכרון בכל אובייקט שתיצרו.

היחידות מורכבות מבלוקים של 16 בייטים (Byte) שכאשר כל בייט מורכב מ 8 ביט (bit).

לכן אם יש משתנה שלוקח 14 בייטים, יתבצע תהליך של Padding – שהמשתנה ייקח בפועל 16 בייטים שמערכת ההפעלה לא תתיחס, אך גם לא תוכל להשתמש במידע שבבייטים ה 14 וה 15.

 
 

דוגמא והסבר:

 

תפיסת הזיכרון של משתנים:

 

 

פרימיטיביים:

boolean = 1 byte.
char/short = 2 bytes
float/int = 4 bytes.
double/long = 8 bytes.

 

אובייקטים:

Integer/Long/Double/Boolean = 16 bytes.

(כי זה כמו מחלקה עם משתנה פרימיטיבי ואז צריך לעשות padding ל 16)

 

מחלקה:

הזיכרון של אובייקט מחלקה מורכב בכלליות מ:

 

1. Object Header – מאכסן מידע כללי על האובייקט.

 

2. זיכרון למשתנים בפרימיטיביים שמוגדרים במחלקה.

 

3. זיכרון למשתנים שהם reference שמוגדרים במחלקה.

 

4. padding – כמה בייטים שלא משתמשים בהם אחרי הבייטים של המידע של האובייקט. נועד בשביל שיהיה נוח לגשת למקום של אובייקט בזיכרון ושלא יצטרכו הרבה ביטים בשביל לייצג מיקום של אובייקט בזיכרון.

 

Object:

 

זה קצת שונה: כל אובייקט (שהוא reference) תופס כפולה של 8 bytes ואם יש פחות אז עושים padding שזה ייקח כפולה של 8.
Object שהוא ריק (לדוגמא מחלקה ריקה) יתפוס מקום של 8 bytes.
אם יש במחלקה הזאת boolean אז היא תתפוס 8 bytes + 1 byte אבל צריך לעשות padding ולכן היא תתפוס 16 bytes.

 

מערך:

 

1. ה Object Header – 12 bytes.

 

2. האלמנטים עצמם:
אם האלמנטים הם פרימיטיביים אז: גודל פרימיטיב * מספר האלמנטים.
אם האלמנטים הם מטיפוס מצביע אז: 4 * מספר האלמנטים.

 

3. padding – אם גודל המערך לא מתחלק ב 8 bytes אז מוסיפים לו bytes שיתחלק.

 

מערך דו מימדי:

 

בניגוד ל c ששם מערך דו מימדי כנראה הופך למערך אחד, ב java מערך דו מימדי הוא מערך אחד שכל איבר בו מצביע לאובייקט שהוא מערך אחר.
נגיד מערך של int[10][10] המקום שלו יהיה:
המערך הראשי יהיה מערך של 10 מצביעים שכל מצביע מצביע למערך אחר, אז הזיכרון שהוא ייקח הוא:
12 bytes(object header) + 4(reference)*10(number of elementes) = 52 + 4(padding) = 56
עכשיו כל מערך אחר יקח:
12 bytes(header) + 4(int) * 10 = 52 + 4(padding) = 56.
ולכן סה”כ הזיכרון שייקח הוא
: 56*11 = 616 bytes.

 

String:

 

String זה קצת שונה, ב java String הוא אובייקט, אפשר להתייחס אליו כ:
Public class String {
(object header) + 3*4(the ints in the String) + 4(the reference to the char array) = 24Char[] c;
	Int a; //integer offset into the index at which the string starts
	Int b; //the length of the string
	Int c; //cached calculations to the hash code

}
נוסיף לזה גודל מערך char:
12(array header) = 12 + 4 (padding)

=>

גודל String ריק 40.

מערך של String באובייקט:

public class Test {

	String[] sArray = new String[10];
	public Test() {

		for(int i = 0; i < 10; i++) {

			sArray[i] = new String();

		}

	}

}
גודל האובייקט:
8(object header) + 4(reference to the String array) = 12 + 4(padding) = 16.
מערך ה String:
sArray הוא מערך של Strings. לכן הוא יהיה ב heap. גודלו:
12(array header) + 4(reference) * 10(number of elements) = 52 + 4(padding) = 56.
נוסיף לזה עכשיו את גודל כל element. ז.א גודל כל String:
(object header) + 3*4(the three ints) + 4(the reference to the char array) = 24
נוסיף לזה גודל מערך char:
12(array header) = 12 + 4 (padding) = 16
=>
גודל String:
40
=>
הגודל של ה sArray הוא:
40*10(The String elements) + 56(The Array Element) = 456.
נוסיף לזה את גודל האובייקט:
456 + 16 = 472.

 

זהו בהצלחה !

Leave a Reply

Your email address will not be published.

אתם יכולים להשתמש באפשרויות ותגי ה-HTMLהבאים: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>