1

I was calling the function "unsafe.allocateMemory" for a bulk of Memory from off-heap. But the value returned is odd.

The run-time environment shows here:

Here is my code:

import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class UnsafeTest{
    public static void main(String[] args){
            try{
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            Unsafe unsafe = (Unsafe) theUnsafe.get(null);
            long addr = unsafe.allocateMemory(16);
            System.out.println("the address is :"+addr);
            unsafe.freeMemory(addr);
            }catch(Exception e){
                    System.out.println(e.getMessage());
            }
    }
}

Result:

I thought something's wrong, because the outcome value is so much bigger than the total memory size(about 6G). I wonder if the value was a memory address ? If so, how could it be allocated as there are not so much memory actually. If not, what the base address of the memory/heap in OS.

bradimus
  • 2,472
  • 1
  • 16
  • 23
James.T
  • 11
  • 1
  • 3

1 Answers1

1

Unsafe#allocateMemory returns something called a "native pointer" which is essentially an address in a virtual memory space associated with the JVM process. The operating system and a Memory Management Unit built into the CPU will be responsible of mapping addresses in this virtual space to addresses in real physical memory.

Because the address space is virtual, the numeric value within it has nothing to do with how much physical memory is available to the system: VM layout and addresses returned from memory allocation functions are at the discretion of the operating system and its core libraries that Java depends on. The OS must also consider hardware limitations imposed on the virtual address space.

See also:

Credits: Comments left by @sotirios-delimanolis and @klitos-kyriacou

anttix
  • 7,709
  • 1
  • 24
  • 25
  • 1
    Thanks,@anttix.Your answer really helped me out. I mixed the Virtual memory up with the physical memory.But there is still something I got confused about.You know,with the compressed Oops enabled,normally the memory are addressed by Word(64-bit) rather than Byte,and we can get compressed address(32-bit) with the native virtual memory address by shiftting 3 bit on the right.We can see it from [link](http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/oops/oop.inline.hpp).But in my case, after shiffed 3 bit, the value is still bigger than 2^32.How java oops be compressed? – James.T Dec 02 '16 at 10:07
  • I think your understanding of compressed oops is slightly incomplete. Here's a quote from Oracle: "Compressed oops represent managed pointers as 32-bit object offsets from the 64-bit Java heap base address." It is the omission of that base value (64bit address) that makes the compressed oops fit into 32 bits See: http://stackoverflow.com/questions/25120546/trick-behind-jvms-compressed-oops – anttix Dec 04 '16 at 09:21