3 回答

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

TA貢獻1806條經驗 獲得超5個贊
即使沒有在構造函數中使用:
public?Neuron(float[]?connection,?float?bias)?{ ????this.connection?=?connection; ????????this.bias?=?bias; }
在執行構造函數之前初始化所有實例字段(so?name
and too)。propability
這些是用默認值初始化的:
private?String?name;?//?nullprivate?float?propability;?//?0F
但是這些默認值沒有任何成本(null
和0
)。
所以不要為此煩惱。
我有一個類,我想使用大約 10 到 10 萬個。因此,我不想不必要地浪費內存位置。
如果是的話,我是否有另一種選擇(除了讓它們成為自己的類之外)來減少內存使用?
如果這些對象有一些公共數據,則在實例之間共享這些數據。依賴共享數據不變性的輕量級模式說明了這種
做法。
對象String
使用它。
完全同意 GhostCat 的評論:即使不使用字段也會消耗內存。不多,但他們消耗。但這對于 Java 中的許多類都是正確的。
例如,我們不會用數組替換所有列表,因為數組通常消耗較少。我們會這樣做,因為在我們的特定情況下,列表內存占用是一個真正令人擔憂的問題。
綜上所述,在優化和改變我們的設計之前,我認為首先要做的是衡量和判斷你是想優化以獲得金子還是堅果。
使用您的實際代碼和main()
產生 100 萬個神經元的方法,我注意到大約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 對于如此多的創建對象來說是相當低的值:100 萬。
如果該類聲明了十幾個未使用的字段,情況就會有所不同。將浪費不可忽略的內存量,并且整個類在設計方面根本不明確:低內聚性。
但事實并非如此。

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