3 回答

TA貢獻1804條經(jīng)驗 獲得超3個贊
我不得不有點不同意:
private float connection[]; private float bias;
第一個(數(shù)組)是引用類型。換句話說:指向某個內(nèi)存區(qū)域的(潛在)指針。顯然:只要該指針指向null
(“無處”),就不需要額外的內(nèi)存。
但是請不要誤會,您的對象本身需要適合內(nèi)存。意思是:當您實例化一個新Neuron
對象時,JVM 會請求存儲 Neuron 對象所需的內(nèi)存量。這意味著:分配了一些內(nèi)存來容納該數(shù)組引用,當然:用于 float原始值的內(nèi)存,它們都是立即分配的。
在該成員字段中存儲的是 0、100.00 還是 10394.283 并不重要:因為 JVM 確保您有足夠的內(nèi)存來容納所需的位和字節(jié)。
因此:當您真的有數(shù)百萬個對象時,對象中的每個浮點字段都會增加 32 位。無論該字段中的值來自何處。
當然,如果您的數(shù)組稍后將包含 5、10 或 1000 個條目,那么這將彌補您的大部分內(nèi)存消耗。但是最初,當您剛剛創(chuàng)建數(shù)百萬個“空”Neuron
對象時,您必須為類中存在的每個字段和任何字段“付費”。
意思是:當 100 個Neuron
對象中只有 1 個需要這兩個字段時,您可以決定:
BaseNeuron
沒有所有 4 個字段的類從該類派生的一個或多個類,添加他們需要的字段
還要注意,從設(shè)計的角度來看,這也是更好的選擇:“空”值總是意味著:額外的代碼來處理它。意思是:如果該數(shù)組可以為空……那么當然,所有處理該字段的代碼都必須在使用它之前檢查該數(shù)組是否為空。將其與:一個沒有該數(shù)組的類與一個您知道該數(shù)組始終已設(shè)置并準備好使用的類進行比較。
我并不是說你絕對必須改變你的設(shè)計,但正如所解釋的:你可以減少你的內(nèi)存占用,并且你可以通過這樣做使你的設(shè)計更清晰。

TA貢獻1806條經(jīng)驗 獲得超5個贊
即使沒有在構(gòu)造函數(shù)中使用:
public?Neuron(float[]?connection,?float?bias)?{ ????this.connection?=?connection; ????????this.bias?=?bias; }
在執(zhí)行構(gòu)造函數(shù)之前初始化所有實例字段(so?name
and too)。propability
這些是用默認值初始化的:
private?String?name;?//?nullprivate?float?propability;?//?0F
但是這些默認值沒有任何成本(null
和0
)。
所以不要為此煩惱。
我有一個類,我想使用大約 10 到 10 萬個。因此,我不想不必要地浪費內(nèi)存位置。
如果是的話,我是否有另一種選擇(除了讓它們成為自己的類之外)來減少內(nèi)存使用?
如果這些對象有一些公共數(shù)據(jù),則在實例之間共享這些數(shù)據(jù)。依賴共享數(shù)據(jù)不變性的輕量級模式說明了這種
做法。
對象String
使用它。
完全同意 GhostCat 的評論:即使不使用字段也會消耗內(nèi)存。不多,但他們消耗。但這對于 Java 中的許多類都是正確的。
例如,我們不會用數(shù)組替換所有列表,因為數(shù)組通常消耗較少。我們會這樣做,因為在我們的特定情況下,列表內(nèi)存占用是一個真正令人擔憂的問題。
綜上所述,在優(yōu)化和改變我們的設(shè)計之前,我認為首先要做的是衡量和判斷你是想優(yōu)化以獲得金子還是堅果。
使用您的實際代碼和main()
產(chǎn)生 100 萬個神經(jīng)元的方法,我注意到大約131 Mo
消耗了:
public static void main(String[] args) {
? ? long beforeUsedMem=Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
? ? List<Neuron> neurons = new ArrayList<>();
? ? for (int i = 0; i < 1_000_000; i++) {
? ? ? neurons.add(new Neuron(new float[] { 0, 15.4F, 1.1F, 2.1F, 3.4F, 4.5F, 8.9F, 158.9F, 8648.9F, 80.9F, 10.9F, 1450.9F, 114.9F, 14.5F, 4444.4F }, 1.9F));
? ? }
? ? long afterUsedMem=Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
? ? long actualMemUsed=(afterUsedMem-beforeUsedMem)/1_000_000;
? ? System.out.println(actualMemUsed + " Mo");
? }
客觀的說,低。
通過刪除未使用的字段,它大約下降到124 Mo(更少 7 Mo):
private String name;
private float propability;
131 Mo 和 124 Mo 對于如此多的創(chuàng)建對象來說是相當?shù)偷闹担?00 萬。
如果該類聲明了十幾個未使用的字段,情況就會有所不同。將浪費不可忽略的內(nèi)存量,并且整個類在設(shè)計方面根本不明確:低內(nèi)聚性。
但事實并非如此。

TA貢獻1818條經(jīng)驗 獲得超8個贊
好吧,是的,它們有所不同,但根據(jù)您的用例/jvm 實現(xiàn)/您擁有的硬件資源,這種不同有多大值得商榷。如果您在具有 500mb 內(nèi)存和 1 個 cpu 的服務(wù)器上運行您的應(yīng)用程序并且您的應(yīng)用程序正在以高速率創(chuàng)建這些對象(隨著時間的推移對象數(shù)量)并且垃圾收集器無法在該速率之后清理,那么最終是的你會遇到內(nèi)存問題。因此,從技術(shù)上和 Java 語言規(guī)范來看,它們占用內(nèi)存,但實際上并基于您的用例,這可能不是任何問題。
添加回答
舉報