PDA

View Full Version : به دست آوردن فضای یک object



JHM9318
دوشنبه 12 اردیبهشت 1390, 22:57 عصر
سلام
چطوری میشه تو جاوا مقدار فضایی رو که یک شی از حافظه اشغال میکنه رو بدست بیارم؟
(آیا چیزی شبیه عملگر sizeof که زبان تو سی هست تو جاوا هم وجود داره؟)
اگه امکانش هست سورس یه برنامه که این کار رو انجام میده هم قرار بدین.

با تشکر

javaphantom
دوشنبه 12 اردیبهشت 1390, 23:56 عصر
سلام
چطوری میشه تو جاوا مقدار فضایی رو که یک شی از حافظه اشغال میکنه رو بدست بیارم؟
(آیا چیزی شبیه عملگر sizeof که زبان تو سی هست تو جاوا هم وجود داره؟)
اگه امکانش هست سورس یه برنامه که این کار رو انجام میده هم قرار بدین.

با تشکر

توی جاوا تمام primitive تایپ ها مثل int long وو اندازه هاشون مشخصه در نتیجه نیازی به sizeof نیست. باقی هم یعنی object ها داستانشون اینکه دست من و تو نیست که malloc مثل c بزنیم و گند بزنیم به حافظه بره پی کارش در نتیجه کار یک جورایی مثل sizeof نداریم به عبارتی size off داریم.

یک راه حله مسخره و بقولی سفسطه آمیز اینه که بیایی object رو serialize کنی بریزی توی byte array بعد طول اون رو حساب کنی که کاملا خنده داره. علتشم اینکه قالب serialize کردن برای عمل remote reflection هست. به عبارتی برای رد وبدل کردن object از بک jvm به jvm دیگه. ربطی به اندازه اون تو حافظه نداره.

یک راه حل خنده داره دیگه اینکه بیایی با کلاس Runtime مقدار حافظه رو بخونی بعد object instance‌ بگیر و دوباره بخونی و از هم کم کنی و بگی انقدر شد مثلا. اینم خنده داره. علتش اینکه که هر موقع garbage collection رو راه بندازی یعنی پیشنهاد بدی که کار کنه وسط کار هر بار مقدار مسخره ای جواب می گیری

اما راه حل.
بر و بچ جاوا کار ایرونی اکثر با متدود public static void main(String[] s) { // body } E
آشنا هستند. نمی خوام وارد ریز ماجرا بشم که چرا static وو و و ولی اینو خوب می دونم که انگار start کار از اینجا شروع می شه یعنی یک متدود reserve شده است.

حالا می خوام وارد یک بحث قشنگ بشم که تا حالا توی این فروم پیش نیومده اون یک متدودی هست که قبل public static void main صدا می شه و اونم هست premain یا همون قبل main.

به کلاسهایی که دارای متدود premain هستند می گن agent. داستان اینه که این امکا توی java 5 اومده که یک کارهایی شبیه به خواسته شما رو جواب می ده. اما ساختار premain هم مثل main که باید حتما یک آرگومان آرایه ای داشته باشه از نوع String اونم برای خودش داستان داره و به شکل زیر هست

public static void premain(String s,Instrumentation instrumentation)

کلاس Instrumentation همون کلاسی هست که تو داری دنبالش می گردی و کارت رو راه می اندازه

به این کد نگاه کن


public class Main {

private int k;

public int getK() {
return k;
}

public void setK(int k) {
this.k = k;
}

public static void premain(String s,Instrumentation instrumentation) {

Main main = new Main();
main.setK(100);

long objectSize = instrumentation.getObjectSize(main);
System.out.println("objectSize = " + objectSize);

}

public static void main(String[] s) {

}
}


اما چه جوری صداش کنیم با دستور
java -javaagent "your jarfile" بشرطی که گفته باشی توی manifest.mf که
Premain-Class: Main

موفق باشی.

JHM9318
چهارشنبه 14 اردیبهشت 1390, 19:32 عصر
دوباره سلام
خیلی ممنون از راهنمایی بسیار کاملتون. فقط چون مبتدی هستم یسری از بخش هاش رو متوجه نشدم!
میشه لطف کنید و بگید که این کاری که تو خط آخر گفتید رو چجوری و برای چی باید انجام بدم؟

توی manifest.mf
Premain-Class: Main