Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I override object with sun.misc.Unsafe?

Tags:

java

unsafe

Can I override one obejct with another if they are instance of same class, their size is the same, using sun.misc.Unsafe?

edit: By "override" I mean to "delete" first object, ant to fill the memory with the second one. Is it possible?

like image 848
kofucii Avatar asked May 18 '11 09:05

kofucii


1 Answers

By "override" I mean to "delete" first object, ant to fill the memory with the second one. Is it possible?

Yes and no.

Yes - If you allocate some memory with Unsafe and write a long, then write another long in it (for example), then yes, you have deleted the first object and filled the memory with a second object. This is similar to what you can do with ByteBuffer. Of course, long is a primitive type, so it is probably not what you mean by 'object'.

Java allows this, because it has the control on allocated memory.

No - Java works with references to objects and only provides references to these objects. Moreover, it tends to move objects around in memory (i.e., for garbage collection).

There is no way to get the 'physical address' and move memory content from one object address to another, if that's what you are trying. Moreover, you can't actually 'delete' the object, because it may be referenced from elsewhere in the code.

However, there is always the possibility of having reference A point to another objectB instead of objectA with A = objectB; You can even make this atomic with Unsafe.compareAndSwapObject(...).

Workaround - Now, let's imagine that reference A1, A2, A3 point to the same objectA. If you want all of them to suddently point to objectB, you can't use Unsafe.compareAndSwapObject(...), because only A1 would point to objectB, while A2 and A3 would still point to objectA. It would not be atomic.

There is a workaround:

public class AtomicReferenceChange {

    public static Object myReference = new Object();

    public static void changeObject(Object newObject) {
        myReference = newObject;
    }

    public static void main(String[] args) {

        System.out.println(AtomicReferenceChange.myReference);
        AtomicReferenceChange.changeObject("333");
        System.out.println(AtomicReferenceChange.myReference);

    }

}

Instead of having multiple references to the same object, you could define a public static reference and have your code use AtomicReferenceChange.myReference everywhere. If you want to change the referenced object atomically, use the static method changeObject(...).

like image 121
Jérôme Verstrynge Avatar answered Oct 29 '22 23:10

Jérôme Verstrynge