![](/img/trans.png)
[英]Build org.joda.time.DateTime with java.time.LocalDate and java.time.LocalTime or java.time.LocalDateTime
[英]Memory consumption java.util.Date vs java.time.LocalDate vs org.joda.time.DateTime
我想知道內存消耗
java.util.Date
java.time.LocalDate
org.joda.time.DateTime
我需要創建一堆具有一些日期的對象,今天它們是很長的時間戳,但這不太好,並且由於我需要日期而在另一側創建了CPU負載。
所以我的問題是:是否有可用的統計數據? 大概如何衡量這種事情?
我不用擔心,您需要數百萬個對象才能真正在服務器上發揮作用。
但是,如果您真的想知道,則可以查看實現以查看每個對象的字段,每個父對象的字段等以及每個引用的對象的字段。 您可以累加每個字段使用的字節數+對象引用的大小(4或8個字節,取決於JVM)加上Java規范中描述的填充。
或者,您可以使用第3方庫(例如java.sizeOf)為您完成此操作。
但是,快速瀏覽一下您要查詢的類的代碼,以下是這些字段:
日期:
private transient long fastTime;
/*
* If cdate is null, then fastTime indicates the time in millis.
* If cdate.isNormalized() is true, then fastTime and cdate are in
* synch. Otherwise, fastTime is ignored, and cdate indicates the
* time.
*/
private transient BaseCalendar.Date cdate;
long
+對具有其自己的字段等的其他類的引用。但是,經過大量的代碼閱讀, cdate
幾乎都是null
因此我們只需要計算對象引用的大小(為null),我認為這不會膨脹使用32位或64位時,對象的大小超出24字節填充的范圍,請使用壓縮的Ops,它會嘗試使用4字節引用而不是8字節引用。 (我認為這是Java 8的默認設置),因此我們可以忽略它。
本地日期:
/**
* The year.
*/
private final int year;
/**
* The month-of-year.
*/
private final short month;
/**
* The day-of-month.
*/
private final short day;
因此, int+short+short
的大小與long
相同,但是您必須考慮保留的每個LocalDate
引用的內存。
約會時間:
private long iMillis;
private Chronology iChronology;
這也是long
+對其他占用內存的對象的引用。
使用SizeOf
當我創建每個對象的實例並在64位Java 8 JVM上對它們使用java.sizeOf時,我得到了以下內存大小(以字節為單位):
javaDate = 24
localDate = 24
dateTime = 16928
如您所見,jodatime的所有支持類都占用大量內存。 但是,當您擁有其他實例時,其中的大部分將被重用。
因此,如果您的long
不在類中,我將繼續使用它們。 但是,如果您將long
封裝在一個類中,或者甚至使用Long
,則LocalDate
似乎是最好的,因為它的內存量相同,加上所有支持的類用於轉換/時區等。我不會使用Date
因為該類是可變的,應該被認為已棄用。
最有效 以長值存儲:8個字節(此外,作為參數傳遞時,它是不可變的)
Java.util.Date
VM 64位:對象的12個+長值的8個+引用BaseCal.Date的4個= 24字節
Sun VM 32位:8 + 8 + 4 = 20 + 4填充= 24字節
(不可推薦,因為沒有任何優勢,可變,需要更多內存)
有實現(IBM嵌入式Java,其中Date僅具有一個字段)(這將是最少16個字節)
本地日期
VM 64位:12 + 4 + 2 + 2 = 20 +4填充= 24字節
VM 32位:8 + 4 + 2 + 2 = 16字節;
在Android Dalvik上:12 + 4 + 4 + 4 = 24字節
喬達日期時間
VM 64位:12 + 8 + 4,用於編年表:= 24字節
VM 32位:8 + 8 + 4,用於編年表參考+ 4個填充= 24字節
大概如何衡量這種事情? 在Sun VM上,您可以使用MAT,它使用Sun VM的特殊功能。 (請參閱Szymon Krawczyk的答案)在其他VM上,它很難衡量,而且我所見的任何代碼(基於堆大小的MemoryTestBench,gc調用等)在某些情況下均會失敗,從而導致內存消耗為負。
最正確的方法是自己計算:
在VM上分配空對象需要8字節的Sun VM 32或12 Sun VM64 + Dalvik +對象大小始終填充為8字節的下一個倍數。
領域
參考字段需要4個字節。 int:4個字節,
長8
短2(在Dalvik上為4),
布爾1字節(Sun),4字節Dalvik;
數組是一個對象+一個int字段(array.length)= 16字節,Dalvik除外,在Dalvik上它出於奇怪的原因需要20字節(如果沒有元素則需要+ 4填充)= 24
根據joda-time的說法,它們提供了處理日期的最佳方法:
http://www.joda.org/joda-time/ http://www.joda.org/joda-time/faq.html
創建Joda-Time是為了從根本上改變Java中的日期和時間處理。 JDK類Date和Calendar的設計很糟糕,有很多錯誤,並且效果奇特。 這是我們開發和使用Joda-Time的一些原因:
根據個人經驗,我同意他們的觀點。 但是,您可以在運行應用程序時使用jvisualvm (jdk / bin)分析工具更好地對其進行分析。
我可以發表評論,但是就內存使用而言,您可以通過執行以下操作來獲取正在運行的應用程序的內存轉儲(堆轉儲): jmap -dump:format=b,file=cheap.bin <pid>
如果使用ECLIPSE,則當然要安裝MAT ,然后在eclipse中打開該文件並比較對象大小。 我用它來找出帶有servlet和Tomcat服務器的Web應用程序中的內存泄漏,這真的很有用
但是,如果您對此不感興趣,請查看該問題以獲取操作系統級別的系統信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.