[Multi-threaded series]unsafe class and Reflection Get Object field value speed comparison

Source: Internet
Author: User

This method is used in the static code blocks of many classes when analyzing atomic packages (e.g. Atomicinteger)

static {      try {        valueoffset = Unsafe.objectfieldoffset            (AtomicInteger.class.getDeclaredField ("value"));      } catch (Exception ex) {throw new Error (ex);}    }

  

So the Objectfieldoffset method is very curious, read the comments also did not understand, search the relevant information, query to a better reply, link in this

Rednaxelafx 2013-06-03sun.misc.unsafe is a tool class used inside the JDK. It exposes Java-layer code by exposing some of the "unsafe" features in Java, allowing the JDK to use Java code more to implement features that are otherwise platform-related and that require the use of native languages such as C or C + +. This class should not be used outside the JDK core class library.

The implementation of the JVM is free to choose how to implement the "layout" of the Java object, that is, where the various parts of the Java object are placed in memory, including the object's instance fields and some metadata. Sun.misc.Unsafe's approach to Object field Access abstracts the object layout, which provides the Objectfieldoffset () method to get the offset of a field relative to the "Start address" of a Java object, and also provides Getint, Getlong, Methods such as GetObject can use the offset obtained earlier to access a field of a Java object.

Each JVM has its own way to implement the layout of the Java object. Oracle/sun the Java object layout used by the HotSpot VM can refer to this blog: http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html
(This content is not too complete but just get started and see if it's enough.) In addition it is only for the default configuration of the hotspot VM for the 32-bit JDK6. )

Colleague Aleksey Shipilev specifically wrote a gadget to show the layout of Java objects:
Https://github.com/shipilev/java-object-layout

After reading it dawned, (< deep into the JVM virtual machine > has explained the structure of the in-memory Java object, 2.3.2: object's memory layout and 2.3.3 Object access positioning)

After curiosity, just think that since it is to get the value, why not reflect, and query a bunch of data, the result of the feedback is unsafe to get the value of faster than reflection, so there is the following test.

Test environment:

  

Tools:

JVM Configuration:

-xms1024m-xmx1024m

Test code:

  

Package Com.iwjw.learn.thread;import sun.misc.unsafe;import java.lang.reflect.field;/** * Atomic packages frequently used class test */public    Class Unsafetest {private static int testtimes = 10000;    private static Field Ageintfield;    private static Field Namestringfield;    private static unsafe unsafe;    private static person person = new person ();            static {try {Ageintfield = Person.class.getDeclaredField ("Age");            Namestringfield = Person.class.getDeclaredField ("name");        unsafe = unsafetest.getunsafeinstance ();        } catch (Exception e) {e.printstacktrace ();        }} public static void Main (string[] args) throws Exception {int times = 1000;        Long reftotal = 0L;        Long unsafetotal = 0L;            for (int i = 0; I < times; i++) {//Test reflection Get field value takes time Reftotal + = Testreflection ();        The time required to test the unsafe class to get the field value Unsafetotal + = Testunsafe (); } System.out.println ("Reflection cosT total msec: "+ (reftotal));    SYSTEM.OUT.PRINTLN ("Unsafe cost Total msec:" + (unsafetotal));         }/** * Test unsafe get field value */private static long Testunsafe () {Long start = System.currenttimemillis ();        int i = Testtimes;        Long Ageoffset = Unsafe.objectfieldoffset (Ageintfield);        Long Nameoffset = Unsafe.objectfieldoffset (Namestringfield);            while (i--> 0) {unsafe.getint (person, ageoffset);        Unsafe.getobject (person, nameoffset); } Long end = System.currenttimemillis ();//System.out.println ("unsafe" + Testtimes + "Times cost msec:" +        (End-start));    return end-start; /** * Test Reflection get field value */private static long Testreflection () {Long start = System.currenttimemillis (        );        int i = Testtimes;        Namestringfield.setaccessible (TRUE);        Ageintfield.setaccessible (TRUE); while (i--> 0) {try {Ageintfield.getint);            Namestringfield.get (person);            } catch (Illegalaccessexception e) {e.printstacktrace (); }} Long end = System.currenttimemillis ();//System.out.println ("reflection" + Testtimes + "Times c        OST msec: "+ (End-start));    return end-start;  }/** * Get unsafe instance * * @return * @throws Exception */private static Unsafe getunsafeinstance () Throws Exception {/* Unsafe unsafe = unsafe.getunsafe () Atomic package uses this method to obtain an Unsafe instance, but in a non-JDK environment , using this method to get the instance used will error java.lang.RuntimeException. Java.lang.SecurityException////////////////By observing that there are fields in the unsafe class Theunsafe by reflection to obtain unsafe instances field        Class.getdeclaredfield ("Theunsafe");        Field.setaccessible (TRUE);    Return (Unsafe) field.get (Unsafe.class);    }}class person {private int: age = 10;    Private String name = "Thank you";    public int getage () {return age; } public void setage (int age) {this.age = age;    } public String GetName () {return name;    } public void SetName (String name) {this.name = name; }}

 

Test results:

type \ Total time consumed (microseconds) \ Fetch number 100 1000 100 XX 100000 1000000 10000000
10 16 57 463 4463 43891
4 5< /td> 12 41 347 3375

    

Conclusion: I have tested many times and the results vary greatly, but there is a general tendency that unsafe gets the object field values faster than reflection, but basically no difference before a certain number of levels. However, by testing the code you can see that unsafe is a class used inside the JDK, and reflection is a class that can be used externally.

Do not use unsafe when you are coding your personal code!!!


PS: About two ways to get the speed of a field my personal thoughts are as follows

Unsafe is to get a fixed offset of a field relative to an object based on the class object (a field is fixed at the time of initialization, as opposed to the address of the memory, see < deep JVM virtual machine >), and then get the value from an object based on the offset

......

  In my preparation to write the principle of reflection, I went to check the next source, and then I was red, the original reflection of the bottom with the unsafe class to achieve, but before a lot of judgment , shame, actually do not need to test, Theoretically the reflection will certainly be slower than the unsafe , alas, or stick it out, warning posterity.

Finally, a similar method is posted in the unsafe class.

  

Gets the offset of the non-static field of the object (get offset of a non-static field in the object in Bytespublic native long Objectfieldoffset (java.lang.ref Lect.  Field field);//Gets the offset of the first element in the array (get offset of the A-a in the array) public native int Arraybaseoffset (java.lang.Class AClass);//Gets the size of an element within the array (get size of an element with the array) public native int Arrayindexscale (Java.lang.Class aclass);//Get Address values in JVM (get address size for your JVMs) public native int addresssize ();

  

  

[Multi-threaded series]unsafe class and Reflection Get Object field value speed comparison

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.