7

I would like to know what is the usage of sun.misc.unsafe.arrayIndexScale, in the javadoc it is said that:

Report the scale factor for addressing elements in the storage allocation of a given array class. However, arrays of "narrow" types will generally not work properly with accessors like getByte(java.lang.Object,int), so the scale factor for such classes is reported as zero.

This method returns an int, but I am not sure what the value means.

Maroun
  • 94,125
  • 30
  • 188
  • 241
Bionix1441
  • 2,135
  • 1
  • 30
  • 65
  • I don't think this is meant for general usage. –  Apr 27 '15 at 14:50
  • 2
    Of course it is not meant for it, it is *unsafe* for a reason :) That however, does not make this a bad question. – meskobalazs Apr 27 '15 at 14:50
  • why are you using something from a `sun.*` package, those are not intended to be public! **You should not be using these classes especially if you have to ask questions like this.** –  Apr 27 '15 at 14:50
  • 2
    it is unsafe sure, but there is no harm in understanding how it works and what the is the value returned by this method. – Bionix1441 Apr 27 '15 at 14:52
  • 1
    Ask Sun for the sources. Maybe they will help you understand the code. –  Apr 27 '15 at 14:52
  • 3
    The method gives you Java object memory layout information. This is used to determine the amount of memory that the given array is occupying. Scale Factor is a term that represents how much a given quantity, in this case memory, is being multiplied by to represent the total. You **should not use the method that you are trying to use; UNSAFE**. However, there are safer versions that you can use: staticFieldBase or staticFieldOffset – Evan Bechtol Apr 27 '15 at 14:56
  • I hope I have understood what you said correctly. So if this method returns 4, so 4 * some number gives the total amount of memory occupied by this object right ? – Bionix1441 Apr 27 '15 at 15:06
  • 1
    If the method returns 4, the memory used by the object is 4 bytes. – J Atkin Apr 27 '15 at 15:22
  • 5
    The suggested duplicate does not make sense because it does not answer the question at all. @EvanBechtol has a great answer, so we should reopen so that he can post it. – JasonMArcher Apr 27 '15 at 17:14
  • @apsillers Thanks for the update! Just posted my comment as an answer. – Evan Bechtol Apr 27 '15 at 19:45
  • @JAtkin I don't think that you are correct. For example: `UNSAFE.arrayIndexScale(Long[].class)` will report 4 (meaning 4 bytes) per each slot in the array (a reference with `UseCompressedOops` enabled), while `UNSAFE.arrayIndexScale(long[].class)` will report 8, because a long occupies 8 bytes. – Eugene Jul 04 '23 at 20:17

2 Answers2

2

The method gives you Java object memory layout information.

This is used to determine the amount of memory that the given array is occupying. Scale Factor is a term that represents how much a given quantity, in this case memory, is being multiplied by to represent the total. You should not use the method that you are trying to use; it's UNSAFE.

However, there are safer versions that you can use: staticFieldBase or staticFieldOffset.

Evan Bechtol
  • 2,855
  • 2
  • 18
  • 36
  • Can you explain the relationship between `arrayIndexScale`, `staticFieldBase` and `staticFieldOffset`? – Samuel Edwin Ward Aug 04 '15 at 22:29
  • @Ceki I wasn’t patronizing OP. The information that I shared is widely available. OP needs to know the risks and potential safer solutions. Your comment does not provide any meaningful improvement to my answer. Please feel free to add if you feel that I missed anything – Evan Bechtol Nov 12 '19 at 18:33
0

imo, an example should make this far easier to understand:

long [] longs = {1L, 2L, 3L};
long offset = UNSAFE.arrayBaseOffset(long[].class);
long indexScale = UNSAFE.arrayIndexScale(long[].class);

long rawIndex = offset + 2 * indexScale;
System.out.println(UNSAFE.getLong(longs, rawIndex));

The last line will print 3 meaning we are trying to get to the 3-rd index.

Another example of just that method would be:

long indexScale = UNSAFE.arrayIndexScale(Long[].class);
System.out.println(indexScale);

which will print 4, but running it with -XX:-UseCompressedOops, will print 8.

Eugene
  • 117,005
  • 15
  • 201
  • 306