Java直接記憶體讀寫的例子

來源:互聯網
上載者:User

標籤:red   就是   通過   image   取數   dir   htm   generated   app   

在Hotspot JVM上,我們能夠直接對記憶體進行讀寫操作。該類的allocateMemory方法用於申請分配記憶體,putAddress和getAddress方法用於對直接記憶體進行讀寫。 

本文將通過sun.misc.Unsafe給出一個直接讀寫記憶體的例子。 

注意:這隻是一個例子,只是用來驗證通過sun.misc.Unsafe來實現直接讀寫記憶體的可能性。但是,這樣做並沒有安全保證,而且稍微有點疏忽將可能導致JVM崩潰。 

Unsafe類的三個方法:allocateMemory,putAddress和getAddress如下: 

Java代碼  
  1. /** 
  2.           * Fetches a native pointer from a given memory address.  If the address is 
  3.           * zero, or does not point into a block obtained from {@link 
  4.           * #allocateMemory}, the results are undefined. 
  5.           * 
  6.           * <p> If the native pointer is less than  bits wide, it is extended as 
  7.           * an unsigned number to a Java long.  The pointer may be indexed by any 
  8.           * given byte offset, simply by adding that offset (as a simple integer) to 
  9.           * the long representing the pointer.  The number of bytes actually read 
  10.           * from the target address maybe determined by consulting {@link 
  11.           * #addressSize}. 
  12.           * 
  13.           * @see #allocateMemory 
  14.           */  
  15.          public native long getAddress(long address);  
  16.        
  17.          /** 
  18.           * Stores a native pointer into a given memory address.  If the address is 
  19.           * zero, or does not point into a block obtained from {@link 
  20.           * #allocateMemory}, the results are undefined. 
  21.           * 
  22.           * <p> The number of bytes actually written at the target address maybe 
  23.           * determined by consulting {@link #addressSize}. 
  24.           * 
  25.           * @see #getAddress(long) 
  26.           */  
  27.          public native void putAddress(long address, long x);  
  28.        
  29.          /// wrappers for malloc, realloc, free:  
  30.        
  31.          /** 
  32.           * Allocates a new block of native memory, of the given size in bytes.  The 
  33.           * contents of the memory are uninitialized; they will generally be 
  34.           * garbage.  The resulting native pointer will never be zero, and will be 
  35.           * aligned for all value types.  Dispose of this memory by calling {@link 
  36.           * #freeMemory}, or resize it with {@link #reallocateMemory}. 
  37.           * 
  38.           * @throws IllegalArgumentException if the size is negative or too large 
  39.           *         for the native size_t type 
  40.           * 
  41.           * @throws OutOfMemoryError if the allocation is refused by the system 
  42.           * 
  43.           * @see #getByte(long) 
  44.           * @see #putByte(long, byte) 
  45.           */  
  46.          public native long allocateMemory(long bytes);  

    

1. long allocateMemory(long bytes) 
申請分配記憶體 
2. long getAddress(long address) 和void putAddress(long address, long x) 
對直接記憶體進行讀寫。 


因為Unsafe這個類的訪問是受限的,只有rt.jar中的類才能使用Unsafe的功能,它的構造方法是私人的,所以,我們不能通過new來建立執行個體。但是,可以通過反射的方法來擷取Unsafe執行個體。 

下面就是一個直接存取記憶體的一個例子: 

Java代碼  
  1. import java.lang.reflect.Field;  
  2.   
  3. import sun.misc.Unsafe;  
  4.   
  5. public class DirectMemoryAccess {  
  6.   
  7.     public static void main(String[] args) {  
  8.   
  9.         /* 
  10.          * Unsafe的建構函式是私人的,不能通過new來獲得執行個體。 
  11.          *  
  12.          *  通過反射來擷取 
  13.          */  
  14.         Unsafe unsafe = null;  
  15.         Field field = null;  
  16.         try {  
  17.             field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");  
  18.             /* 
  19.              * private static final Unsafe theUnsafe = new Unsafe(); 
  20.              *  
  21.              * 因為field的修飾符為 private static final, 
  22.              * 需要將setAccessible設定成true,否則會報java.lang.IllegalAccessException 
  23.              */  
  24.             field.setAccessible(true);  
  25.             unsafe = (Unsafe) field.get(null);  
  26.         } catch (SecurityException e) {  
  27.             // TODO Auto-generated catch block  
  28.             e.printStackTrace();  
  29.         } catch (NoSuchFieldException e) {  
  30.             // TODO Auto-generated catch block  
  31.             e.printStackTrace();  
  32.         } catch (IllegalArgumentException e) {  
  33.             // TODO Auto-generated catch block  
  34.             e.printStackTrace();  
  35.         } catch (IllegalAccessException e) {  
  36.             // TODO Auto-generated catch block  
  37.             e.printStackTrace();  
  38.         }  
  39.   
  40.         long oneHundred = 100;  
  41.         byte size = 1;  
  42.   
  43.         /* 
  44.          * 調用allocateMemory分配記憶體 
  45.          */  
  46.         long memoryAddress = unsafe.allocateMemory(size);  
  47.   
  48.         /* 
  49.          * 將100寫入到記憶體中 
  50.          */  
  51.         unsafe.putAddress(memoryAddress, oneHundred);  
  52.   
  53.         /* 
  54.          * 記憶體中讀取資料  
  55.          */  
  56.         long readValue = unsafe.getAddress(memoryAddress);  
  57.   
  58.         System.out.println("Val : " + readValue);  
  59.     }  
  60. }  



輸出結果: 
Val : 100 

如果,想要查閱Unsafe的原始碼,請參考下面的連結. 
http://www.docjar.com/html/api/sun/misc/Unsafe.java.html 

原文 轉自 :http://blog.csdn.net/joe_007/article/details/38964407

Java直接記憶體讀寫的例子

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.