日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Java基礎(chǔ)之Unsafe內(nèi)存操作不安全類詳解

瀏覽:191日期:2022-08-11 09:52:21
簡介

Unsafe類使Java擁有了像C語言的指針一樣操作內(nèi)存空間的能力,直接操作內(nèi)存就意味著

1、不受jvm管理,也就意味著無法被GC,需要我們手動GC,稍有不慎就會出現(xiàn)內(nèi)存泄漏。

2、Unsafe的不少方法中必須提供原始地址(內(nèi)存地址)和被替換對象的地址,偏移量要自己計算,一旦出現(xiàn)問題就是JVM崩潰級別的異常,會導致整個JVM實例崩潰,表現(xiàn)為應(yīng)用程序直接crash掉。

3、直接操作內(nèi)存,也意味著其速度更快,在高并發(fā)的條件之下能夠很好地提高效率。

Unsafe 類

public final class Unsafe

Unsafe類是'final'的,不允許繼承。

Unsafe 屬性

private static final Unsafe theUnsafe;public static final int INVALID_FIELD_OFFSET = -1;public static final int ARRAY_BOOLEAN_BASE_OFFSET;public static final int ARRAY_BYTE_BASE_OFFSET;public static final int ARRAY_SHORT_BASE_OFFSET;public static final int ARRAY_CHAR_BASE_OFFSET;public static final int ARRAY_INT_BASE_OFFSET;public static final int ARRAY_LONG_BASE_OFFSET;public static final int ARRAY_FLOAT_BASE_OFFSET;public static final int ARRAY_DOUBLE_BASE_OFFSET;public static final int ARRAY_OBJECT_BASE_OFFSET;public static final int ARRAY_BOOLEAN_INDEX_SCALE;public static final int ARRAY_BYTE_INDEX_SCALE;public static final int ARRAY_SHORT_INDEX_SCALE;public static final int ARRAY_CHAR_INDEX_SCALE;public static final int ARRAY_INT_INDEX_SCALE;public static final int ARRAY_LONG_INDEX_SCALE;public static final int ARRAY_FLOAT_INDEX_SCALE;public static final int ARRAY_DOUBLE_INDEX_SCALE;public static final int ARRAY_OBJECT_INDEX_SCALE;public static final int ADDRESS_SIZE;

這些屬性都是在類加載時初始化,它們都是一些類型數(shù)組指針。

Unsafe 靜態(tài)加載

static {registerNatives();Reflection.registerMethodsToFilter(Unsafe.class, new String[]{'getUnsafe'});theUnsafe = new Unsafe();ARRAY_BOOLEAN_BASE_OFFSET = theUnsafe.arrayBaseOffset(boolean[].class);ARRAY_BYTE_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);ARRAY_SHORT_BASE_OFFSET = theUnsafe.arrayBaseOffset(short[].class);ARRAY_CHAR_BASE_OFFSET = theUnsafe.arrayBaseOffset(char[].class);ARRAY_INT_BASE_OFFSET = theUnsafe.arrayBaseOffset(int[].class);ARRAY_LONG_BASE_OFFSET = theUnsafe.arrayBaseOffset(long[].class);ARRAY_FLOAT_BASE_OFFSET = theUnsafe.arrayBaseOffset(float[].class);ARRAY_DOUBLE_BASE_OFFSET = theUnsafe.arrayBaseOffset(double[].class);ARRAY_OBJECT_BASE_OFFSET = theUnsafe.arrayBaseOffset(Object[].class);ARRAY_BOOLEAN_INDEX_SCALE = theUnsafe.arrayIndexScale(boolean[].class);ARRAY_BYTE_INDEX_SCALE = theUnsafe.arrayIndexScale(byte[].class);ARRAY_SHORT_INDEX_SCALE = theUnsafe.arrayIndexScale(short[].class);ARRAY_CHAR_INDEX_SCALE = theUnsafe.arrayIndexScale(char[].class);ARRAY_INT_INDEX_SCALE = theUnsafe.arrayIndexScale(int[].class);ARRAY_LONG_INDEX_SCALE = theUnsafe.arrayIndexScale(long[].class);ARRAY_FLOAT_INDEX_SCALE = theUnsafe.arrayIndexScale(float[].class);ARRAY_DOUBLE_INDEX_SCALE = theUnsafe.arrayIndexScale(double[].class);ARRAY_OBJECT_INDEX_SCALE = theUnsafe.arrayIndexScale(Object[].class);ADDRESS_SIZE = theUnsafe.addressSize();}private static native void registerNatives();

Unsafe 構(gòu)造函數(shù)

private Unsafe() {}

Unsafe 對象不能直接通過 new Unsafe(),它的構(gòu)造函數(shù)是私有的。

Unsafe 實例化方法

public static Unsafe getUnsafe() {Class var0 = Reflection.getCallerClass();if (!VM.isSystemDomainLoader(var0.getClassLoader())) {throw new SecurityException('Unsafe');} else {return theUnsafe;}}

getUnsafe 只能從引導類加載器(bootstrap class loader)加載,非啟動類加載器直接調(diào)用 Unsafe.getUnsafe() 方法會拋出 SecurityException 異常。解決辦法:

1、可以令代碼 ' 受信任 '。運行程序時,通過 JVM 參數(shù)設(shè)置 bootclasspath 選項,指定系統(tǒng)類路徑加上使用的一個 Unsafe 路徑。

java -Xbootclasspath:/usr/jdk1.7.0/jre/lib/rt.jar:. com.Test

2、通過 Java 反射機制,暴力獲取。

Field field = Unsafe.class.getDeclaredField('theUnsafe');field.setAccessible(true);Unsafe unsafe = (Unsafe) field.get(null);

Unsafe 內(nèi)存管理

// 獲取本地指針的大小(單位是byte),通常值為4或者8。常量ADDRESS_SIZE就是調(diào)用此方法。public native int addressSize();// 獲取本地內(nèi)存的頁數(shù),此值為2的冪次方。public native int pageSize();// 分配一塊新的本地內(nèi)存,通過bytes指定內(nèi)存塊的大小(單位是byte),返回新開辟的內(nèi)存的地址。public native long allocateMemory(long var1);// 通過指定的內(nèi)存地址address重新調(diào)整本地內(nèi)存塊的大小,調(diào)整后的內(nèi)存塊大小通過bytes指定(單位為byte)。public native long reallocateMemory(long var1, long var3);// 將給定內(nèi)存塊中的所有字節(jié)設(shè)置為固定值(通常是0)public native void setMemory(Object var1, long var2, long var4, byte var6);// 內(nèi)存復制public native void copyMemory(Object var1, long var2, Object var4, long var5, long var7);// 清除內(nèi)存public native void freeMemory(long var1);

注意:allocateMemory方法申請的內(nèi)存,將直接脫離jvm,gc將無法管理該方式申請的內(nèi)存,用完一定要手動釋放內(nèi)存,防止內(nèi)存溢出;JDK中示例:ByteBuffer.allocateDirect(int capacity)使用DirectByteBuffer,DirectByteBuffer中就是用allocateMemory申請堆外內(nèi)存。

Unsafe 獲取偏移量

// 返回指定變量所屬類中的內(nèi)存偏移量public native long objectFieldOffset(Field var1);// 獲取數(shù)組中第一個元素的地址public native int arrayBaseOffset(Class<?> var1);// 獲取靜態(tài)變量地址偏移值public native long staticFieldOffset(Field var1);// 其實就是數(shù)據(jù)中元素偏移地址的增量,數(shù)組中的元素的地址是連續(xù)的public native int arrayIndexScale(Class<?> var1);

Unsafe 檢查類初始化

// 檢測給定的類是否需要初始化。// 當ensureClassInitialized方法不生效的時候才返回falsepublic native boolean shouldBeInitialized(Class<?> c);// 檢測給定的類是否已經(jīng)初始化。public native void ensureClassInitialized(Class<?> c);

Unsafe 從指定位置讀取

// 從指定內(nèi)存地址處開始讀取一個bytepublic native byte getByte(long var1);// 從指定內(nèi)存地址處開始讀取一個short public native short getShort(long var1);// 從指定內(nèi)存地址處開始讀取一個char public native char getChar(long var1);// 從指定內(nèi)存地址處開始讀取一個int public native int getInt(long var1);// 從指定內(nèi)存地址處開始讀取一個long public native long getLong(long var1);// 從指定內(nèi)存地址處開始讀取一個float public native float getFloat(long var1);// 從指定內(nèi)存地址處開始讀取一個double public native double getDouble(long var1);

Unsafe 向指定位置寫值

// 向指定位置寫入一個int public native void putInt(long var1, int var3);// 向指定位置寫入一個char public native void putChar(long var1, char var3);// 向指定位置寫入一個byte public native void putByte(long var1, byte var3);// 向指定位置寫入一個short public native void putShort(long var1, short var3);// 向指定位置寫入一個long public native void putLong(long var1, long var3);// 向指定位置寫入一個float public native void putFloat(long var1, float var3);// 向指定位置寫入一個double public native void putDouble(long var1, double var3);

Unsafe 對象操作

從指定偏移量處讀取對象屬性(非主存)

public native int getInt(Object var1, long var2);public native Object getObject(Object var1, long var2);public native boolean getBoolean(Object var1, long var2);public native byte getByte(Object var1, long var2);public native short getShort(Object var1, long var2);public native char getChar(Object var1, long var2);public native long getLong(Object var1, long var2);public native float getFloat(Object var1, long var2);public native double getDouble(Object var1, long var2);

向指定偏移量處修改對象屬性(非主存)

public native void putInt(Object var1, long var2, int var4);public native void putObject(Object var1, long var2, Object var4);public native void putBoolean(Object var1, long var2, boolean var4);public native void putByte(Object var1, long var2, byte var4);public native void putShort(Object var1, long var2, short var4);public native void putChar(Object var1, long var2, char var4);public native void putLong(Object var1, long var2, long var4);public native void putFloat(Object var1, long var2, float var4);public native void putDouble(Object var1, long var2, double var4);

向指定偏移量處修改對象屬性(主存)

public native Object getObjectVolatile(Object var1, long var2);public native int getIntVolatile(Object var1, long var2);public native boolean getBooleanVolatile(Object var1, long var2);public native byte getByteVolatile(Object var1, long var2);public native short getShortVolatile(Object var1, long var2);public native char getCharVolatile(Object var1, long var2);public native long getLongVolatile(Object var1, long var2);public native float getFloatVolatile(Object var1, long var2);public native double getDoubleVolatile(Object var1, long var2);

向指定偏移量處修改對象屬性(主存)

public native void putObjectVolatile(Object var1, long var2, Object var4);public native void putIntVolatile(Object var1, long var2, int var4);public native void putBooleanVolatile(Object var1, long var2, boolean var4);public native void putByteVolatile(Object var1, long var2, byte var4);public native void putShortVolatile(Object var1, long var2, short var4);public native void putCharVolatile(Object var1, long var2, char var4);public native void putLongVolatile(Object var1, long var2, long var4);public native void putFloatVolatile(Object var1, long var2, float var4);public native void putDoubleVolatile(Object var1, long var2, double var4);public native void putOrderedObject(Object var1, long var2, Object var4);public native void putOrderedObject(Object var1, long var2, Object var4);public native void putOrderedInt(Object var1, long var2, int var4);public native void putOrderedLong(Object var1, long var2, long var4);

Unsafe CAS操作

public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

針對對象進行CAS操作,本質(zhì)更新對象中指定偏移量的屬性,當原值為var4時才會更新成var5并返回true,否則返回false。舉例:volatile i=0;有多個線程修改i的值,A線程只有在i=1時修改為2,如果代碼如下

if (i == 1) {i = 2;}

這樣時有問題的,if比較完i可能已經(jīng)被別人修改了,這種場景特別適合CAS,使用CAS代碼如下

boolean isUpdate = compareAndSwapInt(object, offset, 1, 2)

相當于讀->判斷->寫一次搞定(實在不能理解CAS,可以這么理解)

Unsafe 線程的掛起和恢復

public native void park(boolean var1, long var2);

阻塞當前線程直到一個unpark方法出現(xiàn)(被調(diào)用)、一個用于unpark方法已經(jīng)出現(xiàn)過(在此park方法調(diào)用之前已經(jīng)調(diào)用過)、線程被中斷或者time時間到期(也就是阻塞超時)。在time非零的情況下,如果isAbsolute為true,time是相對于新紀元之后的毫秒,否則time表示納秒。這個方法執(zhí)行時也可能不合理地返回(沒有具體原因)。并發(fā)包java.util.concurrent中的框架對線程的掛起操作被封裝在LockSupport類中,LockSupport類中有各種版本pack方法,但最終都調(diào)用了Unsafe#park()方法。

public native void unpark(Object var1);

釋放被park創(chuàng)建的在一個線程上的阻塞。這個方法也可以被使用來終止一個先前調(diào)用park導致的阻塞。這個操作是不安全的,因此必須保證線程是存活的(thread has not been destroyed)。從Java代碼中判斷一個線程是否存活的是顯而易見的,但是從native代碼中這機會是不可能自動完成的。

Unsafe 內(nèi)存屏障

public native void loadFence();

在該方法之前的所有讀操作,一定在load屏障之前執(zhí)行完成。

public native void storeFence();

在該方法之前的所有寫操作,一定在store屏障之前執(zhí)行完成

public native void fullFence();

在該方法之前的所有讀寫操作,一定在full屏障之前執(zhí)行完成,這個內(nèi)存屏障相當于上面兩個(load屏障和store屏障)的合體功能。

Unsafe 其他

public native int getLoadAverage(double[] loadavg, int nelems);

獲取系統(tǒng)的平均負載值,loadavg這個double數(shù)組將會存放負載值的結(jié)果,nelems決定樣本數(shù)量,nelems只能取值為1到3,分別代表最近1、5、15分鐘內(nèi)系統(tǒng)的平均負載。如果無法獲取系統(tǒng)的負載,此方法返回-1,否則返回獲取到的樣本數(shù)量(loadavg中有效的元素個數(shù))。實驗中這個方法一直返回-1,其實完全可以使用JMX中的相關(guān)方法替代此方法。

public native void throwException(Throwable ee);

繞過檢測機制直接拋出異常。

到此這篇關(guān)于Java基礎(chǔ)之Unsafe內(nèi)存操作不安全類詳解的文章就介紹到這了,更多相關(guān)Unsafe內(nèi)存操作不安全類內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
激情不卡一区二区三区视频在线| 在线 亚洲欧美在线综合一区| 午夜久久免费观看| 亚洲天堂av影院| 欧美羞羞视频| 亚洲小说欧美另类婷婷| 国产在线欧美| 亚洲少妇在线| 日韩精品视频一区二区三区| 日精品一区二区三区| 青青青国产精品| 国产成人久久| 夜夜嗨一区二区| 91亚洲无吗| 首页国产精品| 悠悠资源网久久精品| 在线国产一区二区| 日韩一区二区三区免费视频| 精品视频久久| 国产在线成人| 日本在线成人| 精品久久久网| 亚洲精品一区二区妖精| 中文一区一区三区免费在线观| 日韩欧美中文字幕在线视频| 美女久久精品| 91久久视频| 国产精品一级| 韩国三级一区| 色8久久久久| 国产videos久久| 久久国产免费| 97精品国产99久久久久久免费| 久久毛片亚洲| 日本一区二区三区视频在线看| 成人国产精品一区二区网站| 国产午夜久久| 国产精品xxx| 亚洲婷婷在线| 国产精品视频一区视频二区| 成人精品天堂一区二区三区| 欧美片第1页综合| 久久香蕉国产| 国产视频一区二区在线播放| 今天的高清视频免费播放成人| 国产欧美日韩免费观看| 国产成人精品一区二区免费看京| 欧美在线综合| 黄毛片在线观看| 欧美在线黄色| 99国产精品自拍| 久久免费精品| 亚州av一区| 国产99久久久国产精品成人免费| 欧美亚洲免费| 日韩一级网站| 亚洲欧洲美洲av| 久久99精品久久久野外观看| 蜜臀久久99精品久久久久宅男| 午夜精品成人av| 国产女人18毛片水真多18精品| 99热精品久久| 久久久精品国产**网站| 日韩中文av| 久久99伊人| 久久在线视频免费观看| 美女久久久久久| 国产精品一区二区三区美女| 视频一区视频二区在线观看| 91精品精品| 国产一区二区色噜噜| 日韩精品福利一区二区三区| 悠悠资源网久久精品| 日韩精品看片| 日韩1区在线| 久久超级碰碰| 日韩在线观看中文字幕| 免费久久精品| 久久精品中文| 激情国产在线| 狂野欧美性猛交xxxx| 久久国内精品视频| 日日夜夜免费精品| 中文字幕av一区二区三区人| 国产美女精品| 亚洲女同一区| 国产精品外国| 亚洲婷婷丁香| 日本一区福利在线| 日产欧产美韩系列久久99| 亚洲小说春色综合另类电影| 香蕉国产精品| 亚洲一区二区毛片| 美国三级日本三级久久99| 中文一区一区三区免费在线观 | 狠狠色综合网| 精品丝袜在线| 91亚洲一区| www在线观看黄色| 人人草在线视频| 在线看片福利| 激情综合自拍| 亚洲有吗中文字幕| 91精品福利观看| 免费亚洲一区| 成人亚洲精品| 午夜精品成人av| 欧美午夜不卡| 亚洲欧美网站| 婷婷综合国产| 国产乱人伦精品一区| 国产精品欧美一区二区三区不卡| 国产精品porn| 五月激情久久| 亚洲在线观看| 亚洲a级精品| 国产精品久久久久久久久久白浆 | 亚洲色诱最新| 婷婷精品在线| 国内精品麻豆美女在线播放视频| 国产成人精选| 红桃视频国产一区| 日韩免费精品| 丰满少妇一区| 久久国产影院| 一区二区日韩免费看| 国产午夜精品一区在线观看| 高清一区二区三区| 黑丝一区二区三区| 国产亚洲一区| 国产福利片在线观看| 女人av一区| 日本一区中文字幕| 久久久久久自在自线| 欧美中文一区二区| 日韩高清成人在线| 午夜精品成人av| 一二三区精品| 国产成人免费视频网站视频社区| 激情视频一区二区三区| 日本色综合中文字幕| 日韩免费视频| 中文字幕一区二区三区在线视频| 欧美91在线| 亚洲激情社区| 久久精品亚洲| 美女国产一区| 国产欧美丝祙| 美女毛片一区二区三区四区| 欧美一区二区三区久久| 亚洲精品一区三区三区在线观看| 亚洲影视一区| 国产精品字幕| 国产日产一区| 久久久人人人| 国产日产精品一区二区三区四区的观看方式| 亚洲风情在线资源| 91精品国产自产精品男人的天堂| 久久精品高清| 国产精品成人国产| 免费日韩av片| 成人欧美一区二区三区的电影| 在线精品视频一区| 天堂日韩电影| 欧美精品1区| 综合国产在线| 美女久久久久| 成人在线视频免费看| 91成人福利| 91精品91| 岛国av免费在线观看| 国产精品视频3p| 日韩专区在线视频| 蜜桃精品在线| 精品女同一区二区三区在线观看| 亚洲我射av| 最新亚洲激情| 亚洲国产综合在线看不卡| 高清一区二区三区| 麻豆精品少妇| 欧美一区精品| 亚洲精品看片| 影音先锋国产精品| 99久久精品网站| 久久久久伊人| 欧美日一区二区在线观看| 午夜在线一区| 亚洲男女av一区二区| 久久人人精品| 日本欧美不卡| 欧美日韩国产观看视频| 精品视频91| 久久午夜影院| 欧美精品91| 欧美aa在线视频| 国产精品久久乐| 麻豆91精品视频| 久久伊人国产| 九九99久久精品在免费线bt| 日韩国产欧美一区二区三区|