導航:首頁 > 編程語言 > javaunsafe

javaunsafe

發布時間:2022-03-12 16:35:09

1. 如何獲得java對象的內存地址

在java中內存中的對象地址是可變的,所以獲得的內存地址有可能會變化。要獲得內存地址也只能通過Unsafe的方法來獲得,如下代碼示例:

packagecom.bijian.study;


importjava.lang.reflect.Field;

importsun.misc.Unsafe;


publicclassAddresser{

//實例化Unsafe 類

privatestaticUnsafeunsafe;


static{

try{

//得到field對象

Fieldfield=Unsafe.class.getDeclaredField("theUnsafe");

//設置獲取地址

field.setAccessible(true);

unsafe=(Unsafe)field.get(null);

}catch(Exceptione){

e.printStackTrace();

}

}


publicstaticlongaddressOf(Objecto)throwsException{


Object[]array=newObject[]{o};


longbaseOffset=unsafe.arrayBaseOffset(Object[].class);

intaddressSize=unsafe.addressSize();

longobjectAddress;

switch(addressSize){

case4:

objectAddress=unsafe.getInt(array,baseOffset);

break;

case8:

objectAddress=unsafe.getLong(array,baseOffset);

break;

default:

thrownewError("unsupportedaddresssize:"+addressSize);

}

return(objectAddress);

}

//列印地址的長度

publicstaticvoidmain(String...args)throwsException{

Objectmine="Hithere".toCharArray();

longaddress=addressOf(mine);

System.out.println("Addess:"+address);


//Verifyaddressworks-

printBytes(address,27);

}

//調用此方法得到地址

publicstaticvoidprintBytes(longobjectAddress,intnum){

//循環列印得到的地址。

for(longi=0;i<num;i++){

intcur=unsafe.getByte(objectAddress+i);

System.out.print((char)cur);

}

System.out.println();

}

}

運行結果:

2. JAVA POI 使用addMergedRegionUnsafe合並單元格操作導致導出時間大大增加,怎麼解決

可以邏輯合並,直接把excel文件後綴名改zip,進去後進入目錄xl/sheet目錄下,打開sheet1.xml如下

這是橫向合並,spans="1:2"中的1代表第1行2代表合並ab兩列,具體可以根據代碼邏輯修改,這種直接修改源文件的方式是效率最快的,邏輯也是最復雜的,具體看自己取捨吧

3. Java 的 DirectBuffer 是什麼東西

DirectByteBuffer 類有一個內部的靜態類 Deallocator,這個類實現了 Runnable 介面並在 run() 方法內釋放了內存:?View CodeJAVA unsafe.freeMemory(address); 那這個 Deallocator 線程是哪裡調用了呢?這里就用到了 Java 的虛引用(PhantomReference),Java 虛引用允許對象被回收之前做一些清理工作。在 DirectByteBuffer 的構造方法中創建了一個 Cleaner:?View CodeJAVA cleaner = Cleaner.create(this , new Deallocator(address, cap) ); 而Cleaner 類繼承了 PhantomReference 類,並且在自己的 clean() 方法中啟動了清理線程,當 DirectByteBuffer 被 GC 之前 cleaner 對象會被放入一個引用隊列(ReferenceQueue),JVM 會啟動一個低優先順序線程掃描這個隊列,並且執行 Cleaner 的 clean 方法來做清理工作。OK,DirectByteBuffer 的實現大概搞清楚了,那我們是否該在自己的代碼中使用 DirectByteBuffer 呢?我個人認為可以適當的使用,使用直接內存確實避免了 GC 問題和內存拷貝的問題,但是我們不得不考慮兩個問題:1)操作系統可能會把 DirectByteBuffer 的內存交換到磁碟上,這樣勢必會影響性能,為了避免這個問題我們不得不對操作系統做相應的配置;2)DirectByteBuffer 申請內存失敗會直接拋出 OutOfMemoryError,對於這種情況,還是要想辦法處理。

4. Java為什麼會引入及如何使用Unsafe

通常我們所說的網站在線客服系統一般是基於網頁的即時通訊工具,它不需要安裝任何軟體,只需要在瀏覽器窗口就可以進行實時交談。網站在線客服系統作為企業網站的客服服務和主動營銷工具,他必須具有主動營銷、客服支持及客戶關系管理方面的功能.結合各類統計數據及歷史資料,可以使企業針對每一位網站頁面的訪客建立檔案以便提供個性化服務,達到變訪客為客戶的營銷目的,使公司形象更為專業化。
在線客服系統給企業帶來了優勢,讓企業和流量有了交流的介面,推薦使用樂盈通客服系統,是一個智能的溝通平台,有效幫助企業實現在線客服的完美服務。

5. 如何使用Unsafe操作內存中的Java類和對象

本文由 ImportNew - 吳際 翻譯自 zeroturnaround。歡迎加入翻譯小組。轉載請參見文章末尾的要求。

讓我們開始展示內存中Java類和對象結構
你可曾好奇過Java內存管理核心構件?你是否問過自己某些奇怪的問題,比如:
一個類在內存中占據多少空間?
我的對象在內存中消耗了多少空間?
對象的屬性在內存中是如何被布局的?
如果這些問題聽起來很熟悉,那麼你就想到了點子上。對於像我們這樣的在RebelLabs的Java極客來說,這些難解的謎題已經在我們腦海中纏繞了很長時間:如果你對探究類檢測器感興趣,想知道如何布局讓所有的類更容易地從內存中取到指定變數,或是想在系統運行時侵入內存中的這些欄位。這就意味著你能切實改變內存中的數據甚至是代碼!
其它可能勾起你興趣的知識點有,「堆外緩存」和「高性能序列化」的實現。這是一對構建在對象緩存結構上很好的實例,揭示了獲取類和實例內存地址的方法,緩存中類和實例的布局以及關於對象成員變數布局的詳細解釋。我們希望盡可能簡單地闡釋這些內容,但是盡管如此這篇文章並不適合Java初學者,它要求具備對Java編程原理有一定的了解。
注意:下面關於類和對象的布局所寫的內容特指Java SE 7,所以不推薦使用者想當然地認為這些適用於過去或將來的Java版本。方便起見,我們在GitHub項目上發布了這篇文章的示例代碼,可以在這里找到 https://github.com/serkan-ozal/ocean-of-memories/tree/master/src/main/java/com/zeroturnaround/rebellabs/oceanofmemories/article1。
在Java中最直接的內存操作方法是什麼?
Java最初被設計為一種安全的受控環境。盡管如此,Java HotSpot還是包含了一個「後門」,提供了一些可以直接操控內存和線程的低層次操作。這個後門類——sun.misc.Unsafe——被JDK廣泛用於自己的包中,如java.nio和java.util.concurrent。但是絲毫不建議在生產環境中使用這個後門。因為這個API十分不安全、不輕便、而且不穩定。這個不安全的類提供了一個觀察HotSpot JVM內部結構並且可以對其進行修改。有時它可以被用來在不適用C++調試的情況下學習虛擬機內部結構,有時也可以被拿來做性能監控和開發工具。
為何變得不安全
sun.misc.Unsafe這個類是如此地不安全,以至於JDK開發者增加了很多特殊限制來訪問它。它的構造器是私有的,工廠方法getUnsafe()的調用器只能被Bootloader載入。如你在下面代碼片段的第8行所見,這個傢伙甚至沒有被任何類載入器載入,所以它的類載入器是null。它會拋出SecurityException 異常來阻止侵入者。
public final class Unsafe {
...
private Unsafe() {}
private static final Unsafe theUnsafe = new Unsafe();
...
public static Unsafe getUnsafe() {
Class cc = sun.reflect.Reflection.getCallerClass(2);
if (cc.getClassLoader() != null)
throw new SecurityException("Unsafe");
return theUnsafe;
}
...
}

幸運的是這里有一個Unsafe的變數可以被用來取得Unsafe的實例。我們可以輕松地編寫一個復制方法通過反射來實現,如下所示:
(http://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/)
public static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe)f.get(null);
} catch (Exception e) {
/* ... */
}
}

Unsafe一些有用的特性
虛擬機「集約化」(VM intrinsification):如用於無鎖Hash表中的CAS(比較和交換)。再比如compareAndSwapInt這個方法用JNI調用,包含了對CAS有特殊引導的本地代碼。在這里你能讀到更多關於CAS的信息:http://en.wikipedia.org/wiki/Compare-and-swap。
主機虛擬機(譯註:主機虛擬機主要用來管理其他虛擬機。而虛擬平台我們看到只有guest VM)的sun.misc.Unsafe功能能夠被用於未初始化的對象分配內存(用allocateInstance方法),然後將構造器調用解釋為其他方法的調用。
你可以從本地內存地址中追蹤到這些數據。使用java.lang.Unsafe類獲取內存地址是可能的。而且可以通過unsafe方法直接操作這些變數!
使用allocateMemory方法,內存可以被分配到堆外。例如當allocateDirect方法被調用時DirectByteBuffer構造器內部會使用allocateMemory。
arrayBaseOffset和arrayIndexScale方法可以被用於開發arraylets,一種用來將大數組分解為小對象、限制掃描的實時消耗或者在大對象上做更新和移動。

6. 求教java中的unsafe.allocateMemory 會導致內存申請失敗嗎

沒有java,這條進程是grep java 的進程,不是java的

用戶名 PID SID 進程的cpu佔用率 進程啟動時間和日期 與進程關聯的終端(tty) 進程使用的總cpu時間 正在執行的命令行命令

7. Java為什麼會引入及如何使用Unsafe

sun.misc.Unsafe至少從2004年Java1.4開始就存在於Java中了。在Java9中,為了提高JVM的可維護性,Unsafe和許多其他的東西一起都被作為內部使用類隱藏起來了。但是究竟是什麼取代Unsafe不得而知,個人推測會有不止一樣來取代它,那麼問題來了,到底為什麼要使用Unsafe?
做一些Java語言不允許但是又十分有用的事情
很多低級語言中可用的技巧在Java中都是不被允許的。對大多數開發者而言這是件好事,既可以拯救你,也可以拯救你的同事們。同樣也使得導入開源代碼更容易了,因為你能掌握它們可以造成的最大的災難上限。或者至少明確你可以不小心失誤的界限。如果你嘗試地足夠努力,你也能造成損害。
那你可能會奇怪,為什麼還要去嘗試呢?當建立庫時,Unsafe中很多(但不是所有)方法都很有用,且有些情況下,除了使用JNI,沒有其他方法做同樣的事情,即使它可能會更加危險同時也會失去Java的「一次編譯,永久運行」的跨平台特性。
對象的反序列化
當使用框架反序列化或者構建對象時,會假設從已存在的對象中重建,你期望使用反射來調用類的設置函數,或者更准確一點是能直接設置內部欄位甚至是final欄位的函數。問題是你想創建一個對象的實例,但你實際上又不需要構造函數,因為它可能會使問題更加困難而且會有副作用。
public class A implements Serializable {
private final int num;
public A(int num) {
System.out.println("Hello Mum");
this.num = num;
}
public int getNum() {
return num;
}
}
在這個類中,應該能夠重建和設置final欄位,但如果你不得不調用構造函數時,它就可能做一些和反序列化無關的事情。有了這些原因,很多庫使用Unsafe創建實例而不是調用構造函數。
Unsafe unsafe = getUnsafe();
Class aClass = A.class;
A a = (A) unsafe.allocateInstance(aClass);
調用allocateInstance函數避免了在我們不需要構造函數的時候卻調用它。
線程安全的直接獲取內存
Unsafe的另外一個用途是線程安全的獲取非堆內存。ByteBuffer函數也能使你安全的獲取非堆內存或是DirectMemory,但它不會提供任何線程安全的操作。你在進程間共享數據時使用Unsafe尤其有用。

import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class PingPongMapMain {
public static void main(String... args) throws IOException {
boolean odd;
switch (args.length < 1 ? "usage" : args[0].toLowerCase()) {
case "odd":
odd = true;
break;
case "even":
odd = false;
break;
default:
System.err.println("Usage: java PingPongMain [odd|even]");
return;
}
int runs = 10000000;
long start = 0;
System.out.println("Waiting for the other odd/even");
File counters = new File(System.getProperty("java.io.tmpdir"), "counters.deleteme");
counters.deleteOnExit();
try (FileChannel fc = new RandomAccessFile(counters, "rw").getChannel()) {
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
long address = ((DirectBuffer) mbb).address();
for (int i = -1; i < runs; i++) {
for (; ; ) {
long value = UNSAFE.getLongVolatile(null, address);
boolean isOdd = (value & 1) != 0;
if (isOdd != odd)
// wait for the other side.
continue;
// make the change atomic, just in case there is more than one odd/even process
if (UNSAFE.compareAndSwapLong(null, address, value, value + 1))
break;
}
if (i == 0) {
System.out.println("Started");
start = System.nanoTime();
}
}
}
System.out.printf("... Finished, average ping/pong took %,d ns%n",
(System.nanoTime() - start) / runs);
}
static final Unsafe UNSAFE;
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (Unsafe) theUnsafe.get(null);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}

當你分別在兩個程序,一個輸入odd一個輸入even,中運行時,可以看到兩個進程都是通過持久化共享內存交換數據的。
在每個程序中,將相同的磁碟緩存映射到進程中。內存中實際上只有一份文件的副本存在。這意味著內存可以共享,前提是你使用線程安全的操作,比如volatile變數和CAS操作。(譯註:CAS Compare and Swap 無鎖演算法
在兩個進程之間有83ns的往返時間。當考慮到System V IPC(進程間通信)大約需要2500ns,而且用IPC volatile替代persisted內存,算是相當快的了。
Unsafe適合在工作中使用嗎?
個人不建議直接使用Unsafe。它遠比原生的Java開發所需要的測試多。基於這個原因建議還是使用經過測試的庫。如果你只是想自己用Unsafe,建議你最好在一個獨立的類庫中進行全面的測試。這限制了Unsafe在你的應用程序中的使用方式,但會給你一個更安全的Unsafe。
總結
Unsafe在Java中是很有趣的一個存在,你可以一個人在家裡隨便玩玩。它也有一些工作的應用程序特別是在寫底層庫的時候,但總的來說,使用經過測試的Unsafe庫比直接用要好。

8. Java為什麼會引入及如何使用Unsafe

sun.misc.Unsafe至少從2004年Java1.4開始就存在於Java中了。在Java9中,為了提高JVM的可維護性,Unsafe和許多其他的東西一起都被作為內部使用類隱藏起來了。但是究竟是什麼取代Unsafe不得而知,個人推測會有不止一樣來取代它

9. C#代碼unsafe public static extern string shibie1(byte* ptr, int w, int h);轉成java代碼應該怎麼轉

你肯定是C# 代碼,C#有指針了??
PS:unsafe 的 還有地址操作,還是按功能重新吧。否則,不涉及地址操作,直接按代碼用 java 類重寫。

閱讀全文

與javaunsafe相關的資料

熱點內容
香港水龍頭陸大潮 瀏覽:753
v18小電影小電影 瀏覽:962
可以用的網站在線觀看 瀏覽:411
推薦個電腦可以看電影的網站 瀏覽:331
私人影院好看的電影 瀏覽:1000
徐錦江的古裝電影 瀏覽:639
noah是什麼干什麼的app 瀏覽:61
APP雲南移動服務密碼怎麼改 瀏覽:750
鬼青春雜作少兒不宜電影 瀏覽:262
小說網站流量排行 瀏覽:458
兒童電影搞笑免費 瀏覽:109
我的世界安卓手機怎麼換號 瀏覽:504
2b2t的伺服器是什麼 瀏覽:214
主角姓秦的重生秦家的小說 瀏覽:362
php十大設計原則 瀏覽:641
怎麼能看出來哪個app有會員 瀏覽:324
艾倫演的警察五點下班什麼電影 瀏覽:647
床戲微電影 瀏覽:535
瀟湘溪苑嬌妻怕打針 瀏覽:433
泰國科幻電影機器人 瀏覽:694