zoukankan      html  css  js  c++  java
  • Java直接内存读写的例子

    在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

  • 相关阅读:
    top 命令
    通过公网访问内网的几种方式总结
    借助IDE到处Runnable JAR 的步骤
    Java SE 基础知识(String,Array)
    Java SE 基础知识(二)
    周记 2014.12.13
    nginx 总结
    在VPS上配置SS
    Markdown 语法手册
    ASCII码表
  • 原文地址:https://www.cnblogs.com/honey01/p/8000070.html
Copyright © 2011-2022 走看看