How to obtain the offset address of the first element of an array by the Unsafe class in Java

practice using the sun.misc.Unsafe class when simulating the tabAt method of ConcurrentHashMap. As shown in the following code, use arrayBaseOffset to get the offset address of the first element of the array, and why both arrays can get the element at the specified location based on this offset address

/**
 * @author Eason
 * @create 2018-05-02 21:15
 **/
public class UnsafeDemo {


    private static int ASHIFT;
    private static long ABASE;

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);

        String[] array1 = new String[]{"abc", "efg", "hij", "kl", "mn", "xyz"};
        String[] array2 = new String[]{"abc1", "efg1", "hij1", "kl1", "mn1", "xyz1"};
        Class<?> ak = String[].class;
        ABASE = unsafe.arrayBaseOffset(ak);
        int scale = unsafe.arrayIndexScale(ak);
        ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
        String array11 = (String) unsafe.getObject(array1, ((long) 2 << ASHIFT) + ABASE);
        String array21 = (String) unsafe.getObject(array2, ((long) 2 << ASHIFT) + ABASE);
        System.out.println(ABASE);
        System.out.println(scale);
        System.out.println(ASHIFT);
        System.out.println(array11);
        System.out.println(array21);
    }
}
Mar.07,2021

Class<?> ak = String[].class;
ABASE = unsafe.arrayBaseOffset(ak);

the ABASE, you get here should be the first element in the string array, which is equivalent to the offset of the starting memory address of the string array object.
this offset is equal to the length of the object header.
64-bit jdk, object header: markword 8-byte, class pointer 4-byte (compression is enabled by default), arr length 4-byte, so ABASE=16
unsafe.getObject (array1, ((long) 2 < < ASHIFT) + ABASE)
array1 should be able to get the starting memory address of this array object, plus the offset. You can get the specific array elements


because what you get is the offset of the first element in the String [] class, and then you pass in array1 and array2 respectively when reading, so it naturally accesses according to the internal offset of these two objects.

Menu