亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java中內存分配的幾種方法

2019-11-26 15:35:40
字體:
來源:轉載
供稿:網友

一、數組分配的上限

Java里數組的大小是受限制的,因為它使用的是int類型作為數組下標。這意味著你無法申請超過Integer.MAX_VALUE(2^31-1)大小的數組。這并不是說你申請內存的上限就是2G。你可以申請一個大一點的類型的數組。比如:

復制代碼 代碼如下:

final long[] ar = new long[ Integer.MAX_VALUE ];

這個會分配16G -8字節,如果你設置的-Xmx參數足夠大的話(通常你的堆至少得保留50%以上的空間,也就是說分配16G的內存,你得設置成-Xmx24G。這只是一般的規則,具體分配多大要看實際情況)。

不幸的是,在Java里,由于數組元素的類型的限制,你操作起內存來會比較麻煩。在操作數組方面,ByteBuffer應該是最有用的一個類了,它提供了讀寫不同的Java類型的方法。它的缺點是,目標數組類型必須是byte[],也就是說你分配的內存緩存最大只能是2G。

二、把所有數組都當作byte數組來進行操作

假設現在2G內存對我們來說遠遠不夠,如果是16G的話還算可以。我們已經分配了一個long[],不過我們希望把它當作byte數組來進行操作。在Java里我們得求助下C程序員的好幫手了――sun.misc.Unsafe。這個類有兩組方法:getN(object, offset),這個方法是要從object偏移量為offset的位置獲取一個指定類型的值并返回它,N在這里就是代表著那個要返回值的類型,而putN(Object,offset,value)方法就是要把一個值寫到Object的offset的那個位置。

不幸的是,這些方法只能獲取或者設置某個類型的值。如果你從數組里拷貝數據,你還需要unsafe的另一個方法,copyMemory(srcObject, srcOffset, destObject,destOffet,count)。這和System.arraycopy的工作方式類似,不過它拷貝的是字節而不是數組元素。

想通過sun.misc.Unsafe來訪問數組的數據,你需要兩個東西:

1.數組對象里數據的偏移量
2.拷貝的元素在數組數據里的偏移量
Arrays和Java別的對象一樣,都有一個對象頭,它是存儲在實際的數據前面的。這個頭的長度可以通過unsafe.arrayBaseOffset(T[].class)方法來獲取到,這里T是數組元素的類型。數組元素的大小可以通過unsafe.arrayIndexScale(T[].class) 方法獲取到。這也就是說要訪問類型為T的第N個元素的話,你的偏移量offset應該是arrayOffset+N*arrayScale。

我們來寫個簡單的例子吧。我們分配一個long數組,然后更新它里面的幾個字節。我們把最后一個元素更新成-1(16進制的話是0xFFFF FFFF FFFF FFFF),然再逐個清除這個元素的所有字節。

復制代碼 代碼如下:

final long[] ar = new long[ 1000 ];
final int index = ar.length - 1;
ar[ index ] = -1; //FFFF FFFF FFFF FFFF

System.out.println( "Before change = " + Long.toHexString( ar[ index ] ));

for ( long i = 0; i < 8; ++i )
{
    unsafe.putByte( ar, longArrayOffset + 8L * index + i, (byte) 0);
    System.out.println( "After change: i = " + i + ", val = "  +  Long.toHexString( ar[ index ] ));
}


想運行上面 這個例子的話,得在你的測試類里加上下面的靜態代碼塊:
復制代碼 代碼如下:

private static final Unsafe unsafe;
static
{
    try
    {
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        unsafe = (Unsafe)field.get(null);
    }
    catch (Exception e)
    {
        throw new RuntimeException(e);
    }
}

private static final long longArrayOffset = unsafe.arrayBaseOffset(long[].class);
輸出的結果是:

復制代碼 代碼如下:

Before change = ffffffffffffffff
After change: i = 0, val = ffffffffffffff00
After change: i = 1, val = ffffffffffff0000
After change: i = 2, val = ffffffffff000000
After change: i = 3, val = ffffffff00000000
After change: i = 4, val = ffffff0000000000
After change: i = 5, val = ffff000000000000
After change: i = 6, val = ff00000000000000
After change: i = 7, val = 0

三、sun.misc.Unsafe的內存分配

上面也說過了,在純Java里我們的能分配的內存大小是有限的。這個限制在Java的最初版本里就已經定下來了,那個時候人們都不敢相像分配好幾個G的內存是什么情況。不過現在已經是大數據的時代了,我們需要更多的內存。在Java里,想獲取更多的內存有兩個方法:


1.分配許多小塊的內存,然后邏輯上把它們當作一塊連續的大內存來使用。
2.使用sun.misc.Unsafe.allcateMemory(long)來進行內存分配。
第一個方法只是從算法的角度來看比較有意思一點,所以我們還是來看下第二個方法。

sun.misc.Unsafe提供了一組方法來進行內存的分配,重新分配,以及釋放。它們和C的malloc/free方法很像:

1.long Unsafe.allocateMemory(long size)――分配一塊內存空間。這塊內存可能會包含垃圾數據(沒有自動清零)。如果分配失敗的話會拋一個java.lang.OutOfMemoryError的異常。它會返回一個非零的內存地址(看下面的描述)。
2.Unsafe.reallocateMemory(long address, long size)――重新分配一塊內存,把數據從舊的內存緩沖區(address指向的地方)中拷貝到的新分配的內存塊中。如果地址等于0,這個方法和allocateMemory的效果是一樣的。它返回的是新的內存緩沖區的地址。
3.Unsafe.freeMemory(long address)――釋放一個由前面那兩方法生成的內存緩沖區。如果address為0什么也不干 。

這些方法分配的內存應該在一個被稱為單寄存器地址的模式下使用:Unsafe提供了一組只接受一個地址參數的方法(不像雙寄存器模式,它們需要一個Object還有一個偏移量offset)。通過這種方式分配的內存可以比你在-Xmx的Java參數里配置的還要大。

注意:Unsafe分配出來的內存是無法進行垃圾回收的。你得把它當成一種正常的資源,自己去進行管理。

下面是使用Unsafe.allocateMemory分配內存的一個例子,同時它還檢查了整個內存緩沖區是不是可讀寫的:

復制代碼 代碼如下:

final int size = Integer.MAX_VALUE / 2;
final long addr = unsafe.allocateMemory( size );
try
{
    System.out.println( "Unsafe address = " + addr );
    for ( int i = 0; i < size; ++i )
    {
        unsafe.putByte( addr + i, (byte) 123);
        if ( unsafe.getByte( addr + i ) != 123 )
            System.out.println( "Failed at offset = " + i );
    }
}
finally
{
    unsafe.freeMemory( addr );
}

正如你所看見的,使用sun.misc.Unsafe你可以寫出非常通用的內存訪問的代碼:不管是Java里分配的何種內存,你都可以隨意讀寫任意類型的數據。

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩中文字幕在线精品| 国产精品你懂得| 国语自产偷拍精品视频偷| 亚洲а∨天堂久久精品喷水| 欧美极品少妇xxxxⅹ喷水| 日韩视频一区在线| 亚洲国产又黄又爽女人高潮的| 国产日韩视频在线观看| 国内精品久久久久久影视8| 欧美精品在线播放| 亚洲美女av黄| 中文字幕欧美日韩精品| 热99精品只有里视频精品| 一区二区三区 在线观看视| 91国产视频在线播放| 亚洲电影在线看| 欧美激情亚洲另类| 一区二区欧美亚洲| 久久夜色精品国产亚洲aⅴ| 成人免费福利视频| 精品国产区一区二区三区在线观看| 日本精品免费观看| 亚洲人成亚洲人成在线观看| 国产精品电影久久久久电影网| 国产精品欧美风情| 日韩av网址在线观看| 欧美激情中文字幕在线| 亚洲精品资源在线| 亚洲深夜福利在线| 日韩在线精品视频| 一区二区亚洲精品国产| 久久天天躁日日躁| 中文字幕精品—区二区| 久久成人人人人精品欧| 亚洲一二在线观看| 91精品国产高清久久久久久久久| 国产成人精品免费久久久久| 九九热精品在线| 两个人的视频www国产精品| 欧美激情精品久久久久久久变态| 欧洲亚洲妇女av| 九九九热精品免费视频观看网站| 亚洲国产成人一区| 精品欧美一区二区三区| 欧美国产精品人人做人人爱| xxxxxxxxx欧美| 91天堂在线观看| 亚洲欧美日韩爽爽影院| 亚洲一区二区久久久| 久久天天躁狠狠躁夜夜躁| 亚洲国产又黄又爽女人高潮的| 欧美亚洲视频在线观看| 日本sm极度另类视频| 欧美激情视频播放| 97视频网站入口| 青青草精品毛片| 国产黑人绿帽在线第一区| 国产一区二区精品丝袜| 亚洲欧美日韩精品久久亚洲区| 国产精品久久久久久久久男| 4438全国成人免费| 2024亚洲男人天堂| 狠狠躁夜夜躁久久躁别揉| 成人精品在线观看| 精品国产一区二区三区久久狼5月| 国产成人精品免费久久久久| 亚洲成人三级在线| 亚洲色图17p| 国产丝袜一区视频在线观看| 久久久中精品2020中文| 成人欧美在线视频| 中文字幕精品一区久久久久| 久久人体大胆视频| 欧美激情在线观看视频| 91精品免费看| 日韩欧美在线免费观看| 国产精品极品尤物在线观看| 91精品视频观看| 日韩国产欧美精品在线| 亚洲精品国产美女| 91国内免费在线视频| 国产精品久久久久国产a级| 日韩欧美有码在线| 日韩精品视频在线观看免费| 亚洲色图15p| 亚洲男人天堂2023| 亚洲自拍小视频| 91美女片黄在线观| 久久不射电影网| 国产精品欧美风情| 久久久精品一区二区| 2018中文字幕一区二区三区| 亚洲国产精品va在线观看黑人| 国产suv精品一区二区| 久久久国产一区二区三区| 日韩欧美aⅴ综合网站发布| 成人激情视频在线播放| 久久久久久久91| 亚洲精品suv精品一区二区| 青青在线视频一区二区三区| 国产精品一区久久| 中文字幕亚洲天堂| 欧美电影在线免费观看网站| 日本欧美精品在线| 一本色道久久综合狠狠躁篇的优点| 国产精品男人爽免费视频1| 色噜噜国产精品视频一区二区| 欧美大尺度在线观看| 在线日韩av观看| 欧美精品制服第一页| 亚洲欧洲激情在线| 久久久精品999| 精品国产欧美一区二区五十路| 亚洲欧美国产日韩天堂区| 久久久久久美女| 97视频在线观看免费高清完整版在线观看| 国产成人精品免费视频| 亚洲人成毛片在线播放| 亚洲黄色在线观看| 亚洲成人久久网| 国产综合视频在线观看| 国产精品久久久久久久av大片| 精品呦交小u女在线| 亚洲精品一区二区在线| 亚洲奶大毛多的老太婆| 精品人伦一区二区三区蜜桃免费| 亚洲精品福利视频| 精品精品国产国产自在线| 亚洲毛片在线观看.| 欧美精品第一页在线播放| 中文字幕亚洲一区在线观看| 91精品国产一区| 91视频8mav| 欧美在线观看日本一区| 亚洲护士老师的毛茸茸最新章节| 在线观看欧美成人| 日韩中文字幕精品| 国产综合色香蕉精品| 日韩在线免费高清视频| 国产成人精品久久| 91天堂在线视频| 日韩精品在线视频美女| 久久久久久这里只有精品| 国内精品伊人久久| 国产福利视频一区二区| 国产成人自拍视频在线观看| 成人精品在线视频| 亚洲电影免费观看高清完整版在线观看| 国产精品99久久久久久久久久久久| 91av在线免费观看| 久久精品影视伊人网| 亚洲sss综合天堂久久| 久久久国产精彩视频美女艺术照福利| 色综合视频一区中文字幕| 亚洲精品久久久久久久久久久| 国产成人一区二区三区电影| 久久噜噜噜精品国产亚洲综合| 国产成人啪精品视频免费网| 欧美最猛性xxxxx亚洲精品| 青青草精品毛片| 国产成人中文字幕| 日韩精品极品毛片系列视频| 亚洲激情久久久| 亚洲成人a**站|