4

ここで、同じクラスのインスタンス サイズが異なるバージョンの JVM で同じでないという問題が見つかりました ( 1.6.0_21では40、1.6.0_31では24です) 。ただし、コードは同じです。以前に同様の問題に遭遇した人はいますか?または何か提案はありますか?

JDK1.6.0_21

# java -version 
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

# java obj.ObjectSize &

# jps | grep ObjectSize
27251 ObjectSize

# jmap -histo 27251 | grep US_ASCII
 145:             1             40  sun.nio.cs.US_ASCII

JDK1.6.0_31

# java -version
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)

# java obj.ObjectSize &

# jps | grep ObjectSize
26645 ObjectSize

# jmap -histo 26645 | grep US_ASCII
161:             1             24  sun.nio.cs.US_ASCII

ObjectSize.java

package obj;
import java.util.concurrent.TimeUnit;
import sun.nio.cs.US_ASCII;

public class ObjectSize {

    public static void main(String[] args) {
        US_ASCII as = new US_ASCII();
        System.out.println(as);

        try {
            TimeUnit.MINUTES.sleep(5);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
4

3 に答える 3

5

あなたが遭遇していることは、コンパイルされたプログラミング言語がどのように機能するか、特にそれらが VM 内で実行される場合に発生する単なる事実だと思います。

仮想マシンの実装の変更は、同じ Java API を維持している限り、異なるサイズの Java バイトコードを生成するなど、異なる動作をすることが許可されています。

メモリ使用量の違いは本当に大きいですか? メモリ サイズの増加が実際に問題である場合は、そもそもメモリの問題がすでにあったことをあえてお勧めします。

1 つの VM で 50% の容量で作業していて、もう 1 つの VM で上限に達している場合は、コードをさらに深く変更する必要があると思います。または、問題にさらにハードウェアを投入します。;)

于 2013-01-08T09:12:26.887 に答える
2

Java 6 の初期バージョンはサポート-XX:+UseCompressedOopsされていましたが、デフォルトではオフになっていました。(Java 6 の最初のバージョンはこれをまったくサポートしていませんでした) これは、64 ビット JVM での参照が 64 ビットだったことを意味します。新しい JVM では、ヒープが 32 GB 未満の場合、32 ビット参照が使用されます。これは、オブジェクトが 8 バイトにアラインされているため、32 ビット参照で 2^32 * 8 バイトをアドレス指定できるため、これを行うことができます。

注: US_ASCII は Charset から 3 つのフィールドを継承します

private final String name;          // tickles a bug in oldjavac
private final String[] aliases;     // tickles a bug in oldjavac
private Set<String> aliasSet = null;

これらの参照は 4 バイト小さいので 12 バイト節約できますが、オブジェクトは 8 バイトにアラインされているため、合計で 16 バイト節約できます。

圧縮 oops を使用すると、使用されるメモリの量が削減されます。

Hotspot JVM の圧縮 oops

ところで:このクラスを直接使用するのではなく、代わりに使用しますStandardCharset.US_ASCII

于 2013-01-08T09:23:01.917 に答える
1

Do you have any suggestions?

If the usage of memory is that important to you, don't use the 64-bit version of 1.6.0_21. Switch to the 32-bit version, or a more recent patch level. Or better yet, Java 7. After all 1.6.0_21 is VERY out of date.

Alternatively, run the JVM with the option to explicitly enable compressed oops as described here:

"For JDK 6 before the 6u23 release, use the -XX:+UseCompressedOops flag with the java command to enable the feature."

(But beware that this might tickle bugs in what was ... at that time ... still an experimental JVM feature.)

于 2013-01-08T09:38:22.327 に答える