2017-06-08 1 views
2

JavaのintとInteger変数のメモリ割り当てに疑問があります。メモリを測定するためにInstrumentation.getObjectSize()を使用し、両方の変数に同じサイズを生成します。メモリ内のintの大きさと整数をjavaで合わせる

ObjectSizeFetcher.java

import java.lang.instrument.Instrumentation; 

public class ObjectSizeFetcher { 
    private static Instrumentation instrumentation; 

    public static void premain(String args, Instrumentation inst) { 
     instrumentation = inst; 
    } 

    public static long getObjectSize(Object o) { 
     return instrumentation.getObjectSize(o); 
    } 
} 

Test.java

public class Test { 
public static void main(String[] args) throws Exception { 
     int i=0; 
     Integer i1 = new Integer(0); 
     long value = ObjectSizeFetcher.getObjectSize(i); 
     System.out.println(value);//prints 16 

     long value1 = ObjectSizeFetcher.getObjectSize(i1); 
     System.out.println(value1);//prints 16 
} 
} 

上記の場合には、両方の可変サイズのプリント同じ:以下の私のコードを見つけてください。私の疑問は、intはプリミティブ型でサイズは4バイトです。Integerは参照型で、そのサイズは16バイトですが、この場合、なぜ両方の値が16バイトになるのでしょうか?どちらもヒープ内の同じ量のメモリを使用すると、Javaのメモリに問題が発生しますか?

答えて

2

igetObjectSizeに渡されるとIntegerに自動ボックスされます。

は、だから、の大きさの値が変数、ない元原始intを促進し得ます。

、この動作を回避するプリミティブ例について過負荷getObjectSize構築するには、次のように

public static long getObjectSize(int o) { 
    return Integer.SIZE/8; 
} 

をして。

2

intがプリミティブ型であり、サイズは4バイトとIntegerは、参照型であり、そのサイズは16バイトです。この場合、なぜ両方の値に対して16バイトをretuyrnしますか?

ObjectSizeFetcher.getObjectSize(Object)コールはIntegerintをオートボクシングされているので。

AFAIK、対策の標準APIはありません。プリミティブ型のサイズまたは参照。 1つの理由は、サイズがどこに格納されているかによって異なります。たとえば、(大)byte[]に格納されているバイトは、オブジェクトのフィールドとして格納されているバイトよりも少なくて済む可能性があります。そして、byteが保持されているローカル変数が再び異なる可能性があります。

オーバーロードされたメソッドを書いて、各プリミティブ型に対しての最小値のサイズを返すのは簡単です。参照のサイズは、32ビットまたは64ビットのJVMを使用しているかどうか、圧縮されたoopsが有効かどうかによって異なります。

+0

Wierd。私は今、upvotesの負荷を期待していただろう。ここに私からのものがある。 – Bathsheba

+0

Javaで変数/オブジェクトのサイズを取得する方法はありますか? –

+0

getObjectSizeのオーバーロードを構築し、値をハードコードすることができます。 – Bathsheba

関連する問題