Java 在我的代码中找不到内存泄漏

Java 在我的代码中找不到内存泄漏,java,Java,我使用以下方法在服务器上发出HTTP Get请求,并将响应解析为Java源代码。我在同一时间对多个文件执行此操作。这对于前几个文件非常有效,但经过一段时间后,我遇到了一个异常: Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 在以下行中引发异常:jp.parsenew StringReaderresponseString;我认为问题在于内存泄漏,因为我试图解析的文件不是很大。只有几十行代码。但是我找不

我使用以下方法在服务器上发出HTTP Get请求,并将响应解析为Java源代码。我在同一时间对多个文件执行此操作。这对于前几个文件非常有效,但经过一段时间后,我遇到了一个异常:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
在以下行中引发异常:jp.parsenew StringReaderresponseString;我认为问题在于内存泄漏,因为我试图解析的文件不是很大。只有几十行代码。但是我找不到这个异常的原因。有什么提示吗

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());
    }

为什么你总是用相同的处理代码重复那些catch块?我会抓住一次例外,然后了结它。其他人什么也不做,只是增加了视觉上的混乱

但这不是你问题的答案

这些课程是你的,还是来自图书馆?我猜是图书馆

如果您使用的是Sun JVM,那么您可以下载、安装所有插件,打开它,然后启动您的进程以查看发生了什么。它将显示内存的生成,CPU,线程等。这是一个伟大的工具

为什么不尝试添加finally块并清除数组?你不会在通话之间保留这些数据吧?如果是,其他呼叫者如何查找和使用结果?也许你的解决方案是一张懦弱的地图。如果需要,您将给JVM一个清理的机会

你应该注意螺纹安全。servlet是共享的,因此如果您挂起那个可变对象,您需要担心同步问题。

getChangeSet.addAffectedFile做什么?您可能想使用已经建议的探查器


它是在坚持吗?另外,您可能希望将该方法拆分为多个部分。

为什么不使用内存探查器查看内存的使用情况?您是否创建了内存转储并对其进行了分析?我使用您的工具包,除了作为一个客户之外,我不喜欢任何连接:为什么在while循环中源代码变量会被多次覆盖?jProfiler和YourKit都是很棒的分析器,你可以免费试用它们。此外,请确保您正在关闭读卡器,这可能是内存被占用的地方。是的,应该将其重构为一个try/catch块。那是我的类。你说的是哪一个数组?你打印出元素数的那个数组。我猜你指的是一个局部变量。这只是将传递的字符串添加到arraylist。因此,如果我理解正确的话,它会在每次请求后积累越来越多的数据。这听起来像是你内存泄漏的原因,我不这么认为。我打印出了元素的数量,它不到100。