首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Apache Netty4高内存使用率

Apache Netty4高内存使用率
EN

Stack Overflow用户
提问于 2017-02-24 13:25:45
回答 1查看 909关注 0票数 0

我在下面的代码中做错什么了吗?或者,netty4组件是否存在一些已知的问题,即它的内存使用率很高?

我的问题是:

我使用Camel的netty4组件从套接字中流数据,聚合它,然后在它的途中发送它。

我尝试过许多不同的聚合数据的策略,似乎没有什么能帮助或损害内存的使用。

我的聚合周期为30秒,在这30秒内,数据总计约为1.3MB。

但是,我注意到我的内存使用量每30秒增加一次4MB。我在Linux中使用watch free -m来监控内存消耗。除了运行骆驼进程的终端之外,前台没有其他进程在运行。在运行Camel进程之前,内存的使用是完全稳定的(MB的规模没有波动)。

我已经使用了几乎所有的netty4设置,由Camel文档提供,这对我来说是显而易见的,而且似乎没有任何东西可以减少内存使用量。

我从命令行运行Camel实例

代码语言:javascript
复制
java -Xms200M -Xmx275M -Xss512k -Drolling_log_dir=/logs/ -jar myCamel.jar

我的路线:

代码语言:javascript
复制
from( netty4:tcp://localhost:12345?clientMode=true&textline=true ).routeId( routeId + "A" )
    .log( LoggingLevel.INFO, rollingLogFile, "${body}" )
    .aggregate( constant(true), new StringAggregationStrategy(dataType) )
    .completionInterval( 30000 )
    .to( fileUri );

from( fileUri ).routeId( routeId + "B" )
    .process(doTheThing)
    .to( pushFile )
    .log( "Transferred ${file:name} complete" );

StringAggregationStrategy.java:

代码语言:javascript
复制
package com.aggregators;

import java.io.BufferedWriter; 
import java.io.File; 
import java.io.IOException; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.nio.file.StandardOpenOption;

import org.apache.camel.Exchange; 
import org.apache.camel.processor.aggregate.AggregationStrategy;

public class StringAggregationStrategy implements AggregationStrategy { 
    private static Path tempFileDir; 
    public StringAggregationStrategy(String dataType){ 
        tempFileDir = Paths.get("camelTempAggFileStorage/" + dataType + "/"); 
    }

    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        String newBody = newExchange.getIn().getBody(String.class);
        String exchangeId;
        Path tempAggFilePath;

        if (!Files.exists(tempFileDir)){
            try {
                Files.createDirectories(tempFileDir);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        if (oldExchange == null){
            cleanDirectory(tempFileDir);
            exchangeId = newExchange.getExchangeId();
            tempAggFilePath = Paths.get(tempFileDir.toString() + "/" + exchangeId + ".txt");
        } else{
            File oldFile = oldExchange.getIn().getBody(File.class);
            tempAggFilePath = oldFile.toPath();
        }

        try (BufferedWriter writer = Files.newBufferedWriter(tempAggFilePath, StandardOpenOption.APPEND, StandardOpenOption.CREATE)){
            if (oldExchange == null) {
                writer.write(newBody);
                newExchange.getIn().setBody(tempAggFilePath.toFile());
                return newExchange;
            } else {
                writer.newLine();
                writer.write(newBody);
                oldExchange.getIn().setBody(tempAggFilePath.toFile());

                return oldExchange;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return oldExchange; 

    }

    private void cleanDirectory(Path tempFileDir) {
        for (File tempFile: tempFileDir.toFile().listFiles()){
            if (!tempFile.isDirectory()){
                tempFile.delete();
            }
        }
    }

}

编辑:使用VisualVM并监视应用程序的运行情况,似乎在出现中断管道异常时,Netty开始生成额外的线程,但这些线程从未被清理过。在我的Java程序运行17个小时后,查看我的堆转储,我发现最大的违法者(类的实例数)分别是io.netty.util.Recycler$DefaultHandleio.netty.channel.ChannelOutboundBuffer$Entry,分别占堆中类的20.2% (59,630)和19.8% (58,306)。

关于骆驼如何减轻这些设置,有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2017-02-24 17:31:08

Java将要求尽可能多的内存,直到配置的限制。

即使当GC清除对象(只有在几乎满了时才会清除),它通常也不会将它声称的内存返回给操作系统。它将为将来的对象保留它拥有的malloc()d块。

因此,几乎所有正在创建大量新对象(即使它们是短暂的)的Java程序都会一直占用内存,直到堆达到-Xmx指定的大小为止。

Hotspot做自己的内存管理--也就是说,它malloc()的大块,并按自己的意愿使用它们,而不是每次创建对象时都执行malloc()

因此,free并不是一个很好的工具来查看一个Java程序是否正在运行。

要查看JVM内存内部,可以使用诸如VisualVM之类的工具--然后可以查看堆大小、对象计数等。如果您的程序确实在泄漏内存,您将在这里看到它。

如果您希望您的Java程序使用更少的内存,请将-Xmx设置得更低,这将迫使GC在较小的内存分配中工作。

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

https://stackoverflow.com/questions/42439779

复制
相关文章

相似问题

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