Java中整型的緩存機制

来源:http://www.cnblogs.com/8hao/archive/2016/03/08/5254255.html
-Advertisement-
Play Games

譯文出處: 張洪亮 原文出處:Java Papers 本文將介紹Java中Integer的緩存相關知識。這是在Java 5中引入的一個有助於節省記憶體、提高性能的功能。首先看一個使用Integer的示例代碼,從中學習其緩存行為。接著我們將為什麼這麼實現以及他到底是如何實現的。你能猜出下麵的Java程式


譯文出處: 張洪亮   原文出處:Java Papers

本文將介紹Java中Integer的緩存相關知識。這是在Java 5中引入的一個有助於節省記憶體、提高性能的功能。首先看一個使用Integer的示例代碼,從中學習其緩存行為。接著我們將為什麼這麼實現以及他到底是如何實現的。你能猜出下麵的Java程式的輸出結果嗎。如果你的結果和真正結果不一樣,那麼你就要好好看看本文了。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.javapapers.java;   public class JavaIntegerCache {     public static void main(String... strings) {           Integer integer1 = 3;         Integer integer2 = 3;           if (integer1 == integer2)             System.out.println("integer1 == integer2");         else             System.out.println("integer1 != integer2");           Integer integer3 = 300;         Integer integer4 = 300;           if (integer3 == integer4)             System.out.println("integer3 == integer4");         else             System.out.println("integer3 != integer4");       } }

我們普遍認為上面的兩個判斷的結果都是false。雖然比較的值是相等的,但是由於比較的是對象,而對象的引用不一樣,所以會認為兩個if判斷都是false的。在Java中,==比較的是對象應用,而equals比較的是值。所以,在這個例子中,不同的對象有不同的引用,所以在進行比較的時候都將返回false。奇怪的是,這裡兩個類似的if條件判斷返回不同的布爾值。

上面這段代碼真正的輸出結果:

1 2 integer1 == integer2 integer3 != integer4

Java中Integer的緩存實現

在Java 5中,在Integer的操作上引入了一個新功能來節省記憶體和提高性能。整型對象通過使用相同的對象引用實現了緩存和重用。

適用於整數值區間-128 至 +127。

只適用於自動裝箱。使用構造函數創建對象不適用。

Java的編譯器把基本數據類型自動轉換成封裝類對象的過程叫做自動裝箱,相當於使用valueOf方法:

1 2 Integer a = 10; //this is autoboxing Integer b = Integer.valueOf(10); //under the hood

現在我們知道了這種機制在源碼中哪裡使用了,那麼接下來我們就看看JDK中的valueOf方法。下麵是JDK 1.8.0 build 25的實現:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /**      * Returns an {@code Integer} instance representing the specified      * {@code int} value.  If a new {@code Integer} instance is not      * required, this method should generally be used in preference to      * the constructor {@link #Integer(int)}, as this method is likely      * to yield significantly better space and time performance by      * caching frequently requested values.      *      * This method will always cache values in the range -128 to 127,      * inclusive, and may cache other values outside of this range.      *      * @param  i an {@code int} value.      * @return an {@code Integer} instance representing {@code i}.      * @since  1.5      */     public static Integer valueOf(int i) {         if (i >= IntegerCache.low && i <= IntegerCache.high)             return IntegerCache.cache[i + (-IntegerCache.low)];         return new Integer(i);     }

在創建對象之前先從IntegerCache.cache中尋找。如果沒找到才使用new新建對象。

IntegerCache Class

IntegerCache是Integer類中定義的一個private static的內部類。接下來看看他的定義。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 /**    * Cache to support the object identity semantics of autoboxing for values between    * -128 and 127 (inclusive) as required by JLS.    *    * The cache is initialized on first usage.  The size of the cache    * may be controlled by the {@code -XX:AutoBoxCacheMax=} option.    * During VM initialization, java.lang.Integer.IntegerCache.high property    * may be set and saved in the private system properties in the    * sun.misc.VM class.    */     private static class IntegerCache {       static final int low = -128;       static final int high;       static final Integer cache[];         static {           // high value may be configured by property           int h = 127;           String integerCacheHighPropValue =               sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");           if (integerCacheHighPropValue != null) {               try {                   int i = parseInt(integerCacheHighPropValue);                   i = Math.max(i, 127);                   // Maximum array size is Integer.MAX_VALUE                   h = Math.min(i, Integer.MAX_VALUE - (-low) -1);               } catch( NumberFormatException nfe) {                   // If the property cannot be parsed into an int, ignore it.               }           }           high = h;             cache = new Integer[(high - low) + 1];           int j = low;           for(int k = 0; k < cache.length; k++)               cache[k] = new Integer(j++);             // range [-128, 127] must be interned (JLS7 5.1.7)           assert IntegerCache.high >= 127;       }         private IntegerCache() {}   }

其中的javadoc詳細的說明瞭緩存支持-128到127之間的自動裝箱過程。最大值127可以通過-XX:AutoBoxCacheMax=size修改。 緩存通過一個for迴圈實現。從低到高並創建儘可能多的整數並存儲在一個整數數組中。這個緩存會在Integer類第一次被使用的時候被初始化出來。以後,就可以使用緩存中包含的實例對象,而不是創建一個新的實例(在自動裝箱的情況下)。

實際上這個功能在Java 5中引入的時候,範圍是固定的-128 至 +127。後來在Java 6中,可以通過java.lang.Integer.IntegerCache.high設置最大值。這使我們可以根據應用程式的實際情況靈活地調整來提高性能。到底是什麼原因選擇這個-128到127範圍呢?因為這個範圍的數字是最被廣泛使用的。 在程式中,第一次使用Integer的時候也需要一定的額外時間來初始化這個緩存。

Java語言規範中的緩存行為

Boxing Conversion部分的Java語言規範(JLS)規定如下:

如果一個變數p的值是:

-128至127之間的整數(§3.10.1)

true 和 false的布爾值 (§3.10.3)

‘\u0000’至 ‘\u007f’之間的字元(§3.10.4)

中時,將p包裝成a和b兩個對象時,可以直接使用a==b判斷a和b的值是否相等。

其他緩存的對象

這種緩存行為不僅適用於Integer對象。我們針對所有的整數類型的類都有類似的緩存機制。

有ByteCache用於緩存Byte對象

有ShortCache用於緩存Short對象

有LongCache用於緩存Long對象

有CharacterCache用於緩存Character對象

ByteShortLong有固定範圍: -128 到 127。對於Character, 範圍是 0 到 127。除了Integer以外,這個範圍都不能改變。

問啊-定製化IT教育平臺,牛人一對一服務,有問必答,開發編程社交頭條 官方網站:www.wenaaa.com 下載問啊APP,參與官方懸賞,賺百元現金。

QQ群290551701 聚集很多互聯網精英,技術總監,架構師,項目經理!開源技術研究,歡迎業內人士,大牛及新手有志於從事IT行業人員進入!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在典型的CMS系統中,通常需要為某個欄目指定個友鏈地址,通過指定友鏈地址,該欄目的地址更人性化、方便記憶,也有利用於搜索引擎優化。 但在MVC中,通常需要在應用程式啟動時註冊路由規則,該路由規則又通常和控制器進行了關聯,也就是某個地址通常情況下都是有對應的控制器進行處理的。本文介紹瞭如何在MVC環境...
  • Windows平臺:Flume學習應用—Java寫日誌數據到MongoDB。
  • javaI/O流可根據流向分為輸入和輸出流,根據流數據類型可分為字元流和位元組流。 下麵用一張圖展示I/O流的劃分: 特點: 位元組流:讀到一個位元組就返回一個位元組,並且可以處理諸如MP3,avi,jpg等格式的文件。 字元流:讀到位元組時先按照編碼規則轉化,然後輸出。只能處理純文本數據。 節點流: 類型
  • 1.命名規範 本系列的第一篇,命名風格本就是有關藝術審美,沒有美與醜的絕對標準,本文難免帶有主觀選擇傾向,但是會儘量保持客觀的態度歸納幾種主流的命名風格,僅供參考。制定規範是為了方便團隊溝通和利於代碼維護,雖然並不能符合每個藝術家的胃口。對於獨立開發者,花點時間設計自己的編碼風格也是有助於提高能力的
  • 參考站點:http://www.iteye.com/problems/64517 方法executeUpdate 用於執行 INSERT、UPDATE 或 DELETE 語句以及 SQL DDL(數據定義語言)語句,例如 CREATE TABLE 和 DROP TABLE。INSERT、UPDATE
  • Java反射機制是Java語言被視為準動態語言的關鍵性質。Java反射機制的核心就是允許在運行時通過Java Reflection APIs來取得已知名字的class類的相關信息,動態地生成此類,並調用其方法或修改其域(甚至是本身聲明為private的域或方法)。 也許你使用Java已經很長時間了,
  • import java.sql.*; public class TestJDBC { // orcl為oracle資料庫中的資料庫名,localhost表示連接本機的oracle資料庫 // 1521為連接的埠號 private static String url = "jdbc:oracle:t...
  • 在進行頁面提交的時候有2中方法 1: 直接<input type="submit" value="提交" name="submit"> 2: 通過js進行提交 <input type="button" id="tijiao " onclick="Dosave()">//這個地方對id不能用特殊字元
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...