繁体   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