簡體   English   中英

在我的代碼中找不到內存泄漏

[英]Can't find a memory leak in my code

我有以下方法,使服務器上的HTTP Get請求將響應解析為Java源代碼。 我同時對多個文件執行此操作。 這對於前幾個文件來說效果很好,但是經過一段時間后,我得到了一個例外:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

該行中引發了異常: jp.parse(new StringReader(responseString)); 我認為問題是內存泄漏,因為我要解析的文件不是很大。 只有幾十行代碼。 但是我找不到導致此異常的原因。 有什么提示嗎?

public void retrieveSourceCode() {
            try {
                System.out.println("Try to get: " + getSourceCodeURI());
                String responseString = RestServices.getInstance().sendGetRequestJsonTextToString(getSourceCodeURI());
                JavaSourceFactory jsf = new JavaSourceFactory();
                JavaParser jp = new JavaParser(jsf);
                jp.parse(new StringReader(responseString));
                Iterator<?> iterator = jsf.getJavaSources();
                while(iterator.hasNext()) {
                    JavaSource source =  ((JavaSource) iterator.next());
                    fileName = source.getQName().toString();
                    sourceCode = source.toString();
                }
            } catch (ClientProtocolException e) {
                fileName = "no file name";
                sourceCode = "no sourcecode available";
                e.printStackTrace();
            } catch (IOException e) {
                fileName = "no file name";
                sourceCode = "no sourcecode available";
                e.printStackTrace();
            } catch (RestServicesException e) {
                fileName = "no file name";
                sourceCode = "no sourcecode available";
                e.printStackTrace();
            } catch (RecognitionException e) {
                fileName = "no file name";
                sourceCode = "no sourcecode available";
                e.printStackTrace();
            } catch (TokenStreamException e) {
                fileName = "no file name";
                sourceCode = "no sourcecode available";
                e.printStackTrace();
            }

            if (before == null) {
                beforeSourceCode = "no before sourcecode available";
            } else {
                try {
                    String responseString = RestServices.getInstance().sendGetRequestJsonTextToString(getBeforeVersionURI());
                    JavaSourceFactory jsf = new JavaSourceFactory();
                    JavaParser jp = new JavaParser(jsf);
                    jp.parse(new StringReader(responseString));
                    Iterator<?> iterator = jsf.getJavaSources();
                    while(iterator.hasNext()) {
                        JavaSource source = (JavaSource) iterator.next();
                        beforeSourceCode = source.toString();
                    }
                } catch (ClientProtocolException e) {
                    beforeSourceCode = "no before sourcecode available";
                } catch (RecognitionException e) {
                    beforeSourceCode = "no before sourcecode available";
                    e.printStackTrace();
                } catch (TokenStreamException e) {
                    beforeSourceCode = "no before sourcecode available";
                    e.printStackTrace();
                } catch (IOException e) {
                    beforeSourceCode = "no before sourcecode available";
                    e.printStackTrace();
                } catch (RestServicesException e) {
                    beforeSourceCode = "no before sourcecode available";
                    e.printStackTrace();
                }
            }

            if (after == null) {
                afterSourceCode = "no after sourcecode available";
            } else {
                try {
                    String responseString = RestServices.getInstance().sendGetRequestJsonTextToString(getAfterVersionURI());
                    JavaSourceFactory jsf = new JavaSourceFactory();
                    JavaParser jp = new JavaParser(jsf);
                    jp.parse(new StringReader(responseString));
                    Iterator<?> iterator = jsf.getJavaSources();
                    while(iterator.hasNext()) {
                        JavaSource source = (JavaSource) iterator.next();
                        afterSourceCode = source.toString();
                    }
                } catch (ClientProtocolException e) {
                    afterSourceCode = "no after sourcecode available";
                } catch (RecognitionException e) {
                    afterSourceCode = "no after sourcecode available";
                    e.printStackTrace();
                } catch (TokenStreamException e) {
                    afterSourceCode = "no after sourcecode available";
                    e.printStackTrace();
                } catch (IOException e) {
                    afterSourceCode = "no after sourcecode available";
                    e.printStackTrace();
                } catch (RestServicesException e) {
                    afterSourceCode = "no after sourcecode available";
                    e.printStackTrace();
                }
            }

            getChangeSet().addAffectedFile(getFileName());
    }

getChangeSet().addAffectedFile()什么作用? 您可能想要使用已經建議的分析器?

它堅持了嗎? 另外,您可能需要將該方法拆分為多個部分。

為什么您要繼續在內部使用相同的處理代碼重復這些catch塊? 我會一次捕獲Exception並完成它。 其他人除了增加視覺混亂之外什么也不做。

但這不是您問題的答案。

這些課程是您的,還是來自圖書館的? 我猜這是Apache JAXMe庫。

如果您使用的是Sun JVM,則可以下載Visual VM 1.3.3 ,安裝所有插件,打開它,然后開始執行過程以查看發生了什么。 它會按代,CPU,線程等向您顯示內存。這是一個很棒的工具。

為什么不嘗試添加finally塊並清除數組? 您不會在通話之間保留這些數據,對嗎? 如果是,其他呼叫者如何查找和使用結果? 也許WeakHashMap可能是您的解決方案。 如果需要,您將給JVM一個清理的機會。

您應該注意線程安全性。 Servlet是共享的,因此如果掛在該可變對象上,則需要擔心同步。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM