常见的误解:这会创建多少个对象?
總覽
一個常見的問題是一段代碼創建多少個對象或多少個字符串。 答案通常不是您的想法,也不是您真正需要知道的。 了解何時創建對象是很有用的,但是有很多其他因素通常要考慮的重要得多,這可能意味著應用程序總數不是您所想的。
字符串不是一個單一的對象
字符串包裝char []。 這意味著當您看到新的String時,可能還會涉及到新的char []。 如果您對String做+,則可以使用StringBuilder(來自Java 5.0),它也可以包裝char []。 這意味著通常在Java中創建的char []比String對象更多。 有時char []是JVM中最常見的對象類型。
字符串文字仍然是字符串
一個常見的誤解是String文字不計算在內。 在至少運行一次代碼之后,它們不會添加到總數中,但是大多數情況下,問題是關于一次運行的代碼。 即字符串文字仍然計數。
另一個常見的誤解是字符串文字被加載時。 在Java 6及更早版本中,它們是在加載Class時加載的,但是現在(Java 7+)在首次使用時已加載。 這意味著首次出現String文字的一段代碼將創建新的String對象。
JVM使用字符串,其中很多。
JVM使用Java代碼,并且使用字符串。 用于加載您的類的ClassLoader使用字符串。 您要加載的類的名稱是一個String,所有系統屬性和創建的所有環境變量都是如此,以便您可以運行您的程序,它們都是String,包括值和鍵名。
讓我們考慮一個Hello World程序,并查看創建了多少個String,以便此程序可以運行。 是0、1還是2個字符串,看看是否可以猜測實際創建了多少個字符串。
public class HowManyStrings {public static void main(String[] args) throws IOException {System.out.println("Hello world");System.in.read();} }該程序在System.in.read()上停止; 讓我把堆放了。 假設沒有GC,實用程序jmap可以給出當前堆上對象數量的直方圖計數,這將是創建的數量。
如您所見,字符串的數目為2490。如果我還有更多的環境變量或Java的其他更新,則數字將有所不同。
簡而言之,如果您在代碼中爭論2到5個String,則可以看到,當代碼運行一次時,您可能會丟失大多數String。
但是,如果我多次調用代碼怎么辦?
如果您正在談論數百萬次,這很可能很重要,但這就是問題。 JVM將優化多次調用的代碼,并且它可以做兩件事。
消除死代碼
JIT檢測到的代碼不會做任何有用的事情,可以將其刪除。 JIT非常擅長此操作,很可能您正在查看的示例也沒有做任何有用的事情。 但是,在現實世界的代碼中,希望它可以做一些有用的事情,這是下一個優化有用的地方。
轉義分析
JIT可以查看一個方法(或內聯調用的所有方法后該方法的外觀),并查看對象是否轉義了該方法。 如果它不能逃脫該方法,則可以將其放在堆棧上,或者有效地將其字段解包到堆棧上。 這意味著不會在堆上創建任何對象,并且實際上甚至不必創建對象標頭,它是所有字段,可能不需要創建任何字段。 簡而言之,僅僅因為您在代碼中看到了新的String并不意味著JIT必須實際創建一個對象,只要它對結果沒有影響(除非您在計算創建的對象的數量)
結論
即使是很小的應用程序創建的字符串數量也可能遠遠超過您想像的用途,但是調用了足夠的次數,您可能會發現方法根本不再創建任何對象。
2015-10-07
彼得·勞瑞翻譯自: https://www.javacodegeeks.com/2015/10/common-misconception-how-many-objects-does-this-create.html
總結
以上是生活随笔為你收集整理的常见的误解:这会创建多少个对象?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Activiti中具有单独数据库模式的多
- 下一篇: (linux ftp 文件)