首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用log4j显示响应的堆内存问题

使用log4j显示响应的堆内存问题
EN

Stack Overflow用户
提问于 2015-12-18 11:26:23
回答 2查看 3.3K关注 0票数 3

在我的代码中有一个级别设置为INFO的log4j记录器,如下所示:

代码语言:javascript
复制
String response = "";
response = someRemoteAPICall();
LOGGER.info("Response: "+response); //line 3

因此,在这段代码的第3行,我得到了带有OutOfMemory错误的大型堆转储。

是否可以通过显示日志消息来获取OOM。

我的转储分析显示了下面的Shallow HeapRetained Heap

这个问题只能通过注释掉日志语句或设置要调试的级别而不是信息或其他一些优雅的方法来解决吗?

我迷路了..。

更新:

代码语言:javascript
复制
        BufferedReader in = new BufferedReader(
        new InputStreamReader(con.getInputStream()));
        String inputLine;
        response = new StringBuffer();
        while ((inputLine = in.readLine()) != null) { //OOM
            response.append(inputLine);
        }
        in.close();

同样的情况发生在上面的代码中,用于读取大数据。

这是显示此代码相对于浅堆的保留堆的图像:

我的系统属性:

java.runtime.name - Java(TM) SE Runtime Environment

java.runtime.version - 1.8.0_51-b16

java.vm.specification.name - Java Virtual Machine Specification

java.vm.specification.vendor - Oracle Corporation

java.vm.specification.version - 1.8

java.vm.name - Java HotSpot(TM) 64-Bit Server VM

os.arch - amd64

os.name - Linux

os.version - 3.13.0-61-generic

EN

回答 2

Stack Overflow用户

发布于 2015-12-18 11:31:38

哦,是的,可以。

在日志记录行中使用+连接字符串。这意味着,在日志发生之前,将创建一个带有新char数组的新字符串。

而且,如果您的对象的toString()使用了类似的特性,那么您最终可能会得到许多char[]的副本--这并不是太小。

如果你绝对的必须打印出整个事情,你会更好

代码语言:javascript
复制
LOGGER.info("Response: %s", response);

只有在实际启用日志信息的情况下才会输出字符串。

如果您知道您的文件很大,并且还想保存它,您可以这样做:

代码语言:javascript
复制
 if(LOGGER.isInfoEnabled()) {
    File dump = writeToDumpFile(response);
    LOGGER.info("Response written to %s", dump.getAbsolutePath());
 }

(并创建+实现事业上的writeToDumpFile(Response response) )

更新您的更新

你不知道这队伍会有多长。

相反,试着:

代码语言:javascript
复制
InputStreamReaderin = new InputStreamReader(con.getInputStream());
response = new StringBuilder();
char[] buffer = new byte[1024];
int len = in.read(buffer);
while(len > 0 ) {
    response.append(buffer, 0, len);
    len = in.read(buffer);        
}
in.close();

使用readLine(),您再次创建了整个字符串的副本:-)

如果你只想转储你的部分回复,你可以在第一次读完之后.

票数 2
EN

Stack Overflow用户

发布于 2015-12-18 11:28:53

也许你不应该放弃你的全部反应。它是否会导致66 of的字符串数据?

哦,即使是一个简单的陈述,比如

代码语言:javascript
复制
Object o = new Object();

如果OutOfMemory完全满的话,可能会导致它的出现。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34354590

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档