2

小さなクローラーを作成したところ、ヒープ スペースが不足していることがわかりました (現在、リスト内の URL の数を 300 に制限していますが)。

Java Memory Analyzer を使用すると、コンシューマーがchar[](64MB のうち 45MB、または許容サイズを増やすとさらに増加し​​ます。常に大きくなります) であることがわかりました。

アナライザーは、の内容も教えてくれますchar[]。クローラーによって読み取られた HTML ページが含まれています。

さまざまな設定をさらに詳しく分析し-Xmx[...]mたところ、Java は使用可能なほとんどすべてのスペースout of heapを使用し、3MB サイズのイメージをダウンロードしようとするとすぐに取得されることがわかりました。

Java に 16MB を指定すると 14MB を使用して失敗し、64MB を指定すると 59MB を使用して大きなイメージをダウンロードしようとすると失敗します。

ページの読み取りは、次のコードで行われます (編集および追加.close()):

private String readPage(Website url) throws CrawlerException {
    StringBuffer sourceCodeBuffer = new StringBuffer();
    try {
        URLConnection con = url.getUrl().openConnection();
        con.setConnectTimeout(2000);
        con.setReadTimeout(2000);

        BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String strTemp = "";
        try {
            while(null != (strTemp = br.readLine())) {
                sourceCodeBuffer = sourceCodeBuffer.append(strTemp);
            }
        } finally {
            br.close();
        }
    } catch (IOException e) {
        throw new CrawlerException();
    }

    return sourceCodeBuffer.toString();
}

別の関数は返された文字列を while ループで使用しますが、私の知る限り、文字列が次のページで上書きされるとすぐにスペースが解放されるはずです。

public void run() {
    boolean stop = false;

    while (stop == false) {
        try {
            Website nextPage = getNextPage();

            String source = visitAndReadPage(nextPage);
            List<Website> links = new LinkExtractor(nextPage).extract(source);
            List<Website> images = new ImageExtractor(nextPage).extract(source);

            // do something with links and images, source is not used anymore
        } catch (CrawlerException e) {
            logger.warning("could not crawl a url");
        }
    }
}

以下は、アナライザーが提供する出力の例です。これらがまだ必要な場所を確認したい場合、Analyzer では判断できません。char[]したがって、それらはもう必要ではなく、ガベージコレクションする必要があると思います。常に最大スペースをわずかに下回っているため、Javaガベージ コレクションを行っているようにも見えますが、現時点ではプログラムの実行を維持するために必要なだけです (大きな入力が来ることを考えていません)。

また、明示的System.gc()に 5 秒ごとに呼び出したり、設定後に呼び出してもsource = null;機能しませんでした。

ウェブサイトのコードは、可能な限り保存されているようです。

読み取り文字列を永久に維持するのに似たObjectOutputStreamものを使用していますか? Stringsまたは、Java がこれらの Web サイトをchar[]これほど長い間配列に保持している可能性はありますか?

Class Name                                                                                                                                                                                                                                                                                   | Shallow Heap | Retained Heap | Percentage
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
char[60750] @ 0xb02c3ee0  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Wallpaper Kostenlos - 77.777 E-Wallpapers: Widescreen, 3D, Handy, Sexy Frauen</title><link rel="shortcut icon" href="http://img.e-wallp...|      121.512 |       121.512 |      1,06%
char[60716] @ 0xb017c9b8  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Wallpaper Kostenlos - 77.777 E-Wallpapers: Widescreen, 3D, Handy, Sexy Frauen</title><link rel="shortcut icon" href="http://img.e-wallp...|      121.448 |       121.448 |      1,06%
char[60686] @ 0xb01f3c88  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Wallpaper Kostenlos - 77.777 E-Wallpapers: Widescreen, 3D, Handy, Sexy Frauen</title><link rel="shortcut icon" href="http://img.e-wallp...|      121.384 |       121.384 |      1,06%
char[60670] @ 0xb015ec48  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Wallpaper Kostenlos - 77.777 E-Wallpapers: Widescreen, 3D, Handy, Sexy Frauen</title><link rel="shortcut icon" href="http://img.e-wallp...|      121.352 |       121.352 |      1,06%
char[60655] @ 0xb01d5d08  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Wallpaper Kostenlos - 77.777 E-Wallpapers: Widescreen, 3D, Handy, Sexy Frauen</title><link rel="shortcut icon" href="http://img.e-wallp...|      121.328 |       121.328 |      1,06%
char[60651] @ 0xb009d9c0  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Wallpaper Kostenlos - 77.777 E-Wallpapers: Widescreen, 3D, Handy, Sexy Frauen</title><link rel="shortcut icon" href="http://img.e-wallp...|      121.320 |       121.320 |      1,06%
char[60637] @ 0xb022f418  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Wallpaper Kostenlos - 77.777 E-Wallpapers: Widescreen, 3D, Handy, Sexy Frauen</title><link rel="shortcut icon" href="http://img.e-wallp...|      121.288 |       121.288 |      1,06%

編集

さらにメモリを増やしてテストしたところ、dominator tree

Class Name                                                                                                                                                                                                                                                                                              | Shallow Heap | Retained Heap | Percentage

crawling.Website @ 0xa8d28cb0                                                                                                                                                                                                                                                                           |           16 |       759.776 |      0,15%
|- java.net.URL @ 0xa8d289c0  https://www.google.com/recaptcha/api/image?c=03AHJ_VuuT4CmbxjAoKzWEKOqLaTCyhT-89l3WOeVjekKWW81tdZsnCvpIrQ52aLTw92rP-EUP9ThnzwBwHcRLXG6A0Bpwu11cGttRAUtarmWXhdcTVRoUMLNnJNZeuuA7LedgfTou76nl8ULyuIR3tgo7_lQ21tzzBhpaTSqwYHWyuZGfuRK3z9pgmqRqvI7gE4_4lexjYbkpd62kN...       |           56 |       759.736 |      0,15%
|  |- char[379486] @ 0xa8c6f4f8  <!DOCTYPE html><html lang="en">  <head>  <meta charset="utf-8">  <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">  <title>Google Accounts</title><style type="text/css">  html, body, div, h1, h2, h3, h4, h5, h6, p, img, dl,  dt, dd, ol, ul, li, t...    |      758.984 |       758.984 |      0,15%
|  |- java.lang.String @ 0xa8d28a40  /recaptcha/api/image?c=03AHJ_VuuT4CmbxjAoKzWEKOqLaTCyhT-89l3WOeVjekKWW81tdZsnCvpIrQ52aLTw92rP-EUP9ThnzwBwHcRLXG6A0Bpwu11cGttRAUtarmWXhdcTVRoUMLNnJNZeuuA7LedgfTou76nl8ULyuIR3tgo7_lQ21tzzBhpaTSqwYHWyuZGfuRK3z9pgmqRqvI7gE4_4lexjYbkpd62kNBZ7UIDccO5bx6TqFpf-7Sl...|           24 |           624 |      0,00%
|  |  '- char[293] @ 0xa8d28a58  /recaptcha/api/image?c=03AHJ_VuuT4CmbxjAoKzWEKOqLaTCyhT-89l3WOeVjekKWW81tdZsnCvpIrQ52aLTw92rP-EUP9ThnzwBwHcRLXG6A0Bpwu11cGttRAUtarmWXhdcTVRoUMLNnJNZeuuA7LedgfTou76nl8ULyuIR3tgo7_lQ21tzzBhpaTSqwYHWyuZGfuRK3z9pgmqRqvI7gE4_4lexjYbkpd62kNBZ7UIDccO5bx6TqFpf-7Sl...    |          600 |           600 |      0,00%
|  |- java.lang.String @ 0xa8d289f8  c=03AHJ_VuuT4CmbxjAoKzWEKOqLaTCyhT-89l3WOeVjekKWW81tdZsnCvpIrQ52aLTw92rP-EUP9ThnzwBwHcRLXG6A0Bpwu11cGttRAUtarmWXhdcTVRoUMLNnJNZeuuA7LedgfTou76nl8ULyuIR3tgo7_lQ21tzzBhpaTSqwYHWyuZGfuRK3z9pgmqRqvI7gE4_4lexjYbkpd62kNBZ7UIDccO5bx6TqFpf-7Sl6YmMgFC77kWZR7vvZIPkS...|           24 |            24 |      0,00%
|  |- java.lang.String @ 0xa8d28a10  www.google.com                                                                                                                                                                                                                                                     |           24 |            24 |      0,00%
|  |- java.lang.String @ 0xa8d28a28  /recaptcha/api/image                                                                                                                                                                                                                                               |           24 |            24 |      0,00%

意図から、私は本当に疑問に思っています: なぜ HTML ソースは の一部なのjava.net.URLですか? これは、私が開いた URLConnection からのものですか?

4

6 に答える 6

2

メソッドの最後で、まずリーダーと URL 接続を閉じようとしますreadPagefinallyこのロジックを句に入れると最適です。

開いたままの接続はメモリを使用し、コードで参照しなくなった場合でも、内部によっては GC がメモリを再利用できない場合があります。

更新(コメントに基づく): 接続自体にはclose()メソッドがなく、接続されているすべてのリーダーが閉じられると閉じられます。

于 2012-07-19T16:14:10.513 に答える
1

あなたの情報が、ガベージ コレクションが機能していないという結論につながるかどうかはわかりません。より多くのメモリを割り当てるときに、単にメモリが不足しています。あなたは、GC に適したオブジェクトがあると考えていると言っていますが、JVM はそうではありません。私は推測ではなくJVMを信頼するだろうと確信しています!

アプリのどこか (別の場所) でメモリ リークが発生しています。オブジェクトのどこかにある Web ページのコンテンツ全体への参照を保持しています。そして、それはあなたの空きメモリをいっぱいにしています。

于 2012-07-19T16:23:35.943 に答える
0

Java に 16MB を指定すると 14MB を使用して失敗し、64MB を指定すると 59MB を使用して大きなイメージをダウンロードしようとすると失敗します。

限界に近づいているので、これは驚くべきことではありません。3 MB のイメージは、ロード (解凍) すると 60 MB 以上に解凍できます。最大を 1 GB に増やすことはできますか?

于 2012-07-19T16:21:36.410 に答える
0

特定の時間にいくつのスレッドを実行していますか? ペーストビンで送信した char 配列はスレッド ローカルのようです (リークがないことを意味します)。同時に多くのことを実行している場合、自然にメモリ不足になります。同じ数の URL で 2 つのスレッドを実行してみてください。

于 2012-07-19T18:16:54.583 に答える
0

私が見つけた別の考えられる理由は、部分文字列が元の文字列で使用されていたのと同じ古い大きな char 配列を使用していることです。したがって、部分文字列を保持すると、完全な文字列が保持されます。

于 2012-08-04T17:57:54.563 に答える
0

ガベージ コレクションを妨げている参照がどこかに保持されている可能性があります。これを修正するには、常にいじる必要があります。私は通常、ヒープ分析を備えたプロファイラーから始めます。可能であれば、ページだけをロードする小さなテスト プログラムを作成します。いくつかの大きな画像を含む 3 ~ 4 個の URL のリストから簡単に作業できます。ページに 10 MB 以上の大きな画像が含まれている場合は、プロファイラーで簡単に見つけることができます。最悪のケースは、使用中のライブラリが参照を保持している場合です。小さなテスト プログラムをデバッグするのが最善の方法です。

于 2012-07-19T16:26:00.920 に答える