前言
新人一枚,剛剛入門編程不久,各方面都在學習當中,博文有什么錯誤的地方,希望我們可以多多交流!
最近,在開發App后台過程中,需要將項目部署到雲服務器上。而雲服務器的內存大小卻只有1G。要如何做到較為合理的內存使用,由此引發了我的一些關於內存方面的疑問:
- 一個類的對象占內存多少?其大小由什么決定?
- Java類中過長的方法會不會影響類的對象大小?
- 將過長的方法封裝會不會影響原來的運行速度?
一個或者多個Java對象的內存模型圖
第一種比較簡單的情況:
public class Boy{
private String name;
private int weight;
public void play() {….}
public static void main(String[] args){
Boy b = new Boy();
b.play();
}
}
這是一個簡單的Java類,我們通過這個對象的創建、方法調用來簡單了解Java對象的內存模型,如下圖
上圖的棧中每一個小方框代表一個棧幀,每當執行一個方法時,就會往JVM棧中壓入一個棧幀。
而該棧幀用來保存參數、局部變量和一些其他的數據。
1)類的class文件會被讀入JVM中的PermSpace中,為之創建一個java.lang.Class對象。當要在堆中創建實例對象時,會為該實例對象的class靜態屬性賦值
補充:什么是PermSpace?
是方法區中一塊主要用來存放靜態的類信息和方法信息,靜態的方法和變
量,final標注的常量信息等等。另外該區域的內存不會被GC回收
2)當使用Boy這個類時,JVM會先在PermSpace中尋找是否有對應的class文件,如果還未被加載到內存中,則系統會通過加載、連接、初始化來對該類進行初始化。
3)boy對象運行時就需要找到其實例對象的地址,這個地址由哈希編碼,並記錄在JVM的一張表上。而調用對象的非靜態方法時,也會有個相對應的方法地址(該詞僅為了易於表達)指向PermSpace中的方法。
4)當該對象的引用變量b調用方法play時,會通過堆中的該對象的方法地址,找到相對應的方法,並最終往JVM的棧中在壓入一個棧幀。執行完成相對應的方法后直接彈出該棧幀
第二種多個同類類型的對象的情況:
1)當有多個同類類型的Java對象時,盡管各個對象都有一套自己的不同狀態的成員變量,但是它們的方法地址都是指向的PermSpace中的該類的方法代碼。當調用對象的非靜態方法時,該情況和上述的第(4)點類似