運用共享技術有效地支援大量細粒度的物件。
採用純粹物件方案的問題在於大量細粒度的物件會很快充斥在系統中,從而帶來很高的執行時代價——主要指記憶體需求方面的代價。如何在避免大量細粒度物件問題的同時,讓外部客戶程式仍然能夠透明地使用物件導向的方式來進行操作?這需要用到享元模式,不過應用享元模式是需要進行評估的,也就是說在當前情況下是否會對系統造成效能上的影響,如果會那麼就是用,下面先來看個小例子是如何進行評估的。
假設有乙個字元的類charator,如下:
public class為了方便評估,charator類中的font型別採用自定義的型別:charator
public class在客戶**中使用charator類font
public class }}在客戶**中將charator類例項化了100000次,charator類中有兩個成員,並且有個成員為font型別,font型別中又定義了三個成員,下面將在**注釋中標出要占用的記憶體量:
/// ///上面的**執行會帶來3mb多的記憶體資料,這個對於現在的機器來說算不了什麼,上面例子中是做了100000次的計算,那如果再加兩個數量級到10000000又會怎麼樣了,那就會有300多mb,這個數字肯定是不能接受的,那麼這個時候就要考慮用享元模式了。 看下面改進後的**:如果有n個font物件占用大小為12bytes*n 其實字串型別
///
除了本身占用的4bytes外 還有乙個引用指標要占用4bytes,
///
不過這個 不會構成倍乘效應,也就是當有n個物件時不會
///
以n的倍數增長,所以可以忽略
///
public class
font
/// ///
總共占用2+20+4+8+2=36bytes
///
第三個的4為指向font的指標
///
第四個的8為虛表指標和垃圾**和同步
///
最後的2為char的填充位
///
public class
charator
/// ///
36bytes * 100000=3600000bytes =3600k=3.6mb
///
public class }}
public class上面的**主要是在getfont方法中進行了判斷,如果物件不存在才建立新的例項,否則直接返回儲存在hashtable中的物件。下面來看下享元模式的結構圖:font
}public class
charator
public
font
cfont
public
font
getfont(
string
name)
return
(font
)fonttable[name];
}}public class }}
針對上面結構的完整**:
/// ///物件導向很好地解決了抽象性的問題,但是作為乙個執行在機器中的程式實體,我們需要考慮物件的代價問題。flyweight設計模式主要解決物件導向的代價問題,一般不觸及物件導向的抽象性問題。享元的抽象類
///
public abstract class
flyweight
/// ///
需要共享的具體類
///
public class
conceteflyweight
: flyweight
}/// ///
不需要共享的具體類
///
public class
unsharedconcreteflyeight
: flyweight
}/// ///
乙個工廠類,用來合理建立物件
///
public class
flyweightfactory
return
(flyweight
)dic[key];
}}/// ///
客戶端呼叫
///
public class
}
flyweight採用物件共享的做法來降低系統中物件的個數,從而降低細粒度物件給系統帶來的記憶體壓力。在具體實現方面,要注意物件狀態的處理。
物件的數量太大從而導致物件記憶體開銷加大——什麼樣的數量才算大---這需要我們仔細的根據具體應用情況進行評估,而不能憑空臆斷。
返回開篇(索引)
Java設計模式(12)結構型 享元模式
享元模式是指使用共享物件,用來盡可能減少記憶體使用量以及分享資訊給盡可能多的相似物件 它適合用於只是因重複而導致使用無法令人接受的大量記憶體的大量物件。通常物件中的部分狀態是可以分享。常見做法是把它們放在外部資料結構,當需要使用時再將它們傳遞給享元。使用享元可以節省記憶體的開銷,特別適合處理大量細粒...
設計模式 結構型 享元模式
如果乙個應用程式使用了大量的物件,而大量的這些物件造成了很大的儲存開銷時就應該考慮使用 還有物件的大多數狀態可以外部狀態,如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件。public class flyweighttest class flyweightfactory publi...
GO設計模式 結構型 享元模式
享元模式就是將大量物件共有的部分抽取出來,供這些物件共享使用。而這些元素不同的部分,會以引數的形式注入具體享元的相關方法中。ps 其實感覺有點像sync.pool,本質都是快取共享物件,降低記憶體消耗和減輕gc壓力,但是仔細看下來還是和sync.pool有點區別的 快取共享物件,降低記憶體消耗 在遊...