來源:互聯網
上載者:User
關鍵字
php
c++
objective-c
java
一個類解耦成多個類,從執行個體化一個類到要執行個體化多個類,這樣是不是增加了記憶體的消耗?
回複內容:
一個類解耦成多個類,從執行個體化一個類到要執行個體化多個類,這樣是不是增加了記憶體的消耗?
如果解耦得當,基本不會增加記憶體消耗,因為對象中的方法和參數雖然被分成到了不同的類中,但每個方法和參數佔用空間都沒有變,所有總體記憶體也沒有變。只是在對象資訊棧和指標上多佔一些記憶體,不過這些基本都是可以忽略的。
記憶體可以批量生產,人要計劃生育
如果所有用到這一個類的地方,都需要執行個體化解耦後的所有類,那這個類就沒有必要解耦
是
但人工比記憶體貴得多
就單從語義來看,這是肯定的。
但是記憶體的消耗只是開發的一部分,畢竟還要考慮開發成本,維護成本
看起來沒有太大的差別,只是CPU佔用率後者明顯大一些,當然我只是隨便測了一下,僅供參考~
這種過程可以將功能更加細化,這樣維護起來就能更加輕鬆
因為一個類,就算什麼都不定義,也是會有固定的記憶體消耗的(主要就是class的一些meta資訊了),所以理論上類越多這部分開銷越大。
然而這部分能佔多少呢?幾個位元組而已~
就像前面提到的,記憶體可以批量,人要計劃生育,解耦的目標是為了讓程式的可讀性增強,進而有助於後續的迭代——有良好結構的代碼,帶來的不僅僅是人力的節省,也會帶來程式的擴充性良好,長期看來,能夠實現相同功能的前提下,程式對硬體資源的消耗也會因為良好的設計而減少。
不會有太大的變化,解耦後,將屬性和方法都分到不同的類裡面,記憶體使用量率不會有太大的變化,即使有,可以忽略不計了。總之,利大於弊,何樂而不為呢。
純粹為了可讀性來把一個class分出新的class,而且新的class的生命週期與原本的class完全一樣,則增加memory的耗損。
當然,這些損耗是很小的。可以忽略。
如果新的類的cohesion更好,而且可以late initialization,那麼可以最佳化記憶體使用量,減少記憶體損耗。
比如說,
class User { private String name; private Integer age; private String gender; private String country; private String address; private String zipCode; private String companyName; private String occupation; private String companyAddress; private String favoriteSports; private String favoriteFoods; private String favoriteMovie;}
任何一個User object就要分配12個fields的記憶體空間。
split class後,
class User { private PersonalInfo personal; private Address addr; private WorkInfo work; private Favorites favorites;}
首先,初始化User只需要4個reference的記憶體,不需要初始化12個fields。如果一個使用者的favorites是空的,就無需初始化Favorites的記憶體了。
當然,以上的是很瑣碎的東西。真正有價值的是,不必要再把一大托User傳來傳去,User類駐留記憶體的時間變短:
//假設有一個module只對WorkInfo有興趣class WorkInfoPresentation { void displayWorkInfo(String userId) { // #L0: final User user = SomeUserDAO.getUser(userId); final WorkInfo work = user.getWorkInfo(); // #L1: user的生命週期到此為止,可以被Garbage Collect掉了。 callSomeComplicatedHTMLRenderingService(work); // #L2: 假設傳入的不是work而是user, 那麼user的記憶體就要一直駐留。 } private void callSomeComplicatedHTMLRenderingService(WorkInfo work) { // 假定要花很久時間來運算 }}
較耗費記憶體的User的生命週期在#L0 - #L1,而較輕量的WorkInfo的生命週期在#L0 - #L2。User可能在進入callSomeComplicatedHTMLRenderingService
之前就被GC掉了,從而節省了#L1 - #L2階段的記憶體。
從絕對意義上來說是的,消耗的記憶體增加了。
但是,對象資訊棧和指標上多佔一些記憶體這種消耗是沒必要考慮的,就像是
if (a==b){echo a;} 比 if (a==b) echo a; 需要執行更多的指令一樣。
隨著項目源碼的增加、功能的擴充,維護是非常重要的問題,所以不可能丟了西瓜去撿芝麻。解耦對於維護來說價值就是西瓜,消耗的記憶體就是芝麻(何況還不如芝麻)。