7

Java Swing アプリケーションが Java 6 32 ビットから Java 7 32 ビット update 11 に移行されると、パフォーマンスの問題に直面しています。

アプリケーションは Java Web-start テクノロジを使用しており、サーバーは Tomcat 7 です。クライアント アプリケーションは 1GB のメモリを消費しているため、画面がフリーズしています。

シリアル化されたオブジェクトを交換しています。コードは次のとおりです。

Object object = connection.sendCommand(command); // exchanging serialized object            

public class ConnectionImpl implements Connection {
    public Object sendCommand(Command command) throws Exception {
        URL url = new URL(System.getProperty("serverUrl"));
        URLConnection connection = url.openConnection();
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        oos = new ObjectOutputStream(new BufferedOutputStream(connection
                    .getOutputStream()));
        oos.writeObject(command);
        oos.flush();
        InputStream inputStream = connection.getInputStream();
        ZipInputStream zip = new ZipInputStream(inputStream);
        if (zip.getNextEntry() != null) {
            ois = new ObjectInputStream(zip);
            object = ois.readObject();
        }
        zip.close();
    }
}

// The serialized class
public class CommandImpl implements Command, Serializable {
    private String serviceName;
    private String methodName;
    private Map<String, Object> parameterMap;

// followed by getter & setters
}
  • クライアント マシン: Windows 7 32 ビット、Java 7 update 11 32 ビット
  • サーバー マシン: Windows 64 ビット 2008 R2 Enterprise Server、Java 7 update 11 64 ビット

JVM が更新されるだけで、コードに変更はありません。

Java VisualVM を使用して JDK 1.6 および JDK 1.7 のメモリ スナップショットを取得しました。以下は、スナップショットを含む rar ファイルへのリンクです。

Java VisualVM を使用したメモリ スナップショット Java VisualVM を使用したヒープ ダンプ

NetBeans IDE には、コードを Java 6 から Java 7 に移行するオプションがあります。これに関するリンクは次のとおりです。

https://netbeans.org/kb/docs/java/editor-inspect-transform.html#convert

ソースコード全体を Java 6 から Java 7 に問題なく移行するための適切なオプションでしょうか? または、誰かが問題を引き起こす可能性があると感じていますか? そうすれば、このパフォーマンスの問題をある程度まで解決できるでしょうか?

4

3 に答える 3

6

ObjectOutputStream oos はメソッドで構築されますが、それを閉じたようには見えません。ストリームを閉じると、メモリが解放されます。

ObjectOutputStream はいつガベージ コレクションを取得しますか? ObjectOutputStream と ObjectInputStream は、読み書きされたオブジェクトをメモリに保持します。それはメモリリークのように見えます。

ストリームが確実に閉じられるように、finally ブロックを追加することをお勧めします。あなたが投稿したものからシリアライズされたオブジェクトの存続期間はわかりませんが、readUnshared および writeUnshared メソッドを使用することでメリットが得られる可能性があります。

あなたが書いた:

ソースコード全体を Java 6 から Java 7 に問題なく移行するための適切なオプションでしょうか? または、誰かが問題を引き起こす可能性があると感じていますか? そうすれば、このパフォーマンスの問題をある程度まで解決できるでしょうか?

ツールを使用してコードを 1.7 に更新してもメリットはありません。これを行うと、1.6 でコードを実行できなくなります。Netbean の「パフォーマンス」インスペクションを実行することをお勧めします。また、コードベースに対して FindBugs を実行することを強くお勧めします。

ヒープダンプ

  • jdk 1.7 ダンプは、53M が使用されたときにヒープから取得されました。
  • jdk 1.6 ダンプは、61M が使用されたときに取得されました。

投稿したヒープダンプは、メモリが問題になる前に取得されたように見えるため、それほど役に立ちません。システムが大量のメモリを使用しているときにヒープダンプを取得して、ダンプを調べてメモリが使用されている場所を見つける必要があります。

-XX:+HeapDumpOnOutOfMemoryErrorjvm オプションを追加します。このオプションを使用すると、メモリが不足すると、Java は自動的に独自のヒープダンプを取得します。

スナップショット

** スナップショット アーカイブには 4 つのファイルがありますが、そのうちの 2 つのファイルは重複しており、名前が異なります。サイズとチェックサムを見ると、それらが同じであることがわかります。**

スナップショットはより有益ですが、大量のメモリが使用される前に取得されたようにも見えます。

1.7 スナップショットには、より多くの String インスタンスがあります。

1.6 のスナップショットは次のようになります。 visualvm 画像

1.7 のスナップショットは次のようになります。 ここに画像の説明を入力

String.substring は、基礎となる文字配列を共有しなくなりました。これは、多くの文字列操作を行うコードではかなり大きな違いになる可能性があります。

これらの char[] は、String オブジェクトの実際のデータを保持します。String を保持するオブジェクトと、それらの String がどのように構築されるかを詳しく見ていきます。

于 2013-06-11T00:33:03.710 に答える