天天看點

Java堆外記憶體的使用

在Java中有很多的基本類型,比如:

byte,一個位元組是8位bit,也就是1B

short,16位bit,也就是2B

int,32位bit,也就是4B

long, 64位bit,也就是8B

char,16位bit,也就是2B

float,32位bit,也就是4B

double,64位bit,也就是8B

不同的類型都會按照自己的位數來存儲,并且可以自動進行轉換提升。byte、char、short都可以自動提升為int,如果操作數有long,就會自動提升為long,float和double也是如此。

目前的存儲器,多以byte為通路的最小單元,當一個邏輯上的位址必須分割為實體上的若幹單元時就存在了先放誰後放誰的問題,于是端(endian)的問題應運而生了,對于不同的存儲方法,就有大端(big-endian)和小端(little- endian)兩個描述。

位元組排序按分為大端和小端,概念如下

大端:低位址位 存放 高有效位元組

小端:低位址位 存放 低有效位元組

舉個例子,一個char是有兩個位元組組成的,這兩個位元組存儲可能會顯示成如下的模樣,比如字元a:

現在主流的CPU,intel系列的是采用的little endian的格式存放資料,而motorola系列的CPU采用的是big endian,ARM則同時支援 big和little,網絡程式設計中,TCP/IP統一采用大端方式傳送資料,是以有時我們也會把大端方式稱之為網絡位元組序。特别需要注意的是,C/C++語言編寫的程式裡資料存儲順序是跟編譯平台所在的CPU相關的,而 JAVA編寫的程式則唯一采用big endian方式來存儲資料。

舉個例子說明,我的機子是32位windows的系統,處理器是AMD的。對于一個int型數0x12345678,為友善說明,這裡采用16進制表示。這個數在不同位元組順序存儲的CPU中儲存順序如下:

0x12345678   16進制,兩個數就是一位元組

高有效位元組——>低有效位元組: 12 34 56 78

          低位址位     高低址位

大端:  12  34        56   78

小端: 78  56        34   12

在直接記憶體中,通過allocateDirect(int byte_length)申請直接記憶體。這段記憶體可以了解為一段普通的基于Byte的數組,是以插入和讀取都跟普通的數組差不多。

隻不過提供了基于不同資料類型的插入方法,比如:

put(byte) 插入一個byte

put(byte[]) 插入一個byte數組

putChar(char) 插入字元

putInt(int) 插入Int

putLong(long) 插入long

等等。

它有幾個關鍵的名額:

mark-->position-->limit-->capacity

另外,還有remaining=limit-position。

目前位置——position,position是目前數組的指針,訓示目前資料位置。position可以通過position()獲得,也可以通過position(int)設定。注意:position的位置要比limit小,比mark大。

空間容量——capacity,capacity是目前申請的直接記憶體的容量,它是申請後就不會改變的。capacity則可以通過capacity()方法獲得。

限制大小——limit,我們可能想要改變這段直接記憶體的大小,是以可以通過一個叫做Limit的屬性設定。limit則可以通過limit()獲得,通過limit(int)進行設定。注意limit要比mark和position大,比capacity小。

标記位置——mark, mark,就是一個标記為而已,記錄目前的position的值。常用的場景,就是記錄某一次插入資料的位置,友善下一次進行回溯。

可以使用mark()方法進行标記,mark方法标記目前的position,預設為-1

使用reset()方法進行清除,reset方法重置position的位置為mark的位置,mark不能小于0,否則會出錯

使用rewind()方法進行初始化,重置mark為-1.position為0

使用案例

剩餘空間——remaing,remaing則表示目前的剩餘空間

clear(),這個方法用于清除mark和position,還有limit的位置。

flip(),這個方法主要用于改變limit為目前的position,position為0,主要是用于讀取操作。

compact(),這個方法在讀取一部分資料的時候比較常用。它會把目前的Position移到0,然後position+1移到1,即類似substring(目前位置)的效果。

isDirect()這個方法用于判斷是否是直接記憶體。如果是傳回true,如果不是傳回false。

rewind()這個方法用于重置mark标記。