Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在使用协议缓冲区时,什么可能导致java.lang.OutOfMemoryError出现在这里?_Java_Redis_Protocol Buffers_Jedis - Fatal编程技术网

在使用协议缓冲区时,什么可能导致java.lang.OutOfMemoryError出现在这里?

在使用协议缓冲区时,什么可能导致java.lang.OutOfMemoryError出现在这里?,java,redis,protocol-buffers,jedis,Java,Redis,Protocol Buffers,Jedis,运行下面的代码会导致Java堆空间出现异常 来自.NET并掌握GC在那里工作的方式,我想知道在尝试运行以下内容时,在内存管理方面是否需要考虑: public static void main(String[] args) throws NumberFormatException, ParseException, IOException { Jedis jedis = new Jedis("<HostName>"); TimeSeriesPoints retriev

运行下面的代码会导致Java堆空间出现异常

来自.NET并掌握GC在那里工作的方式,我想知道在尝试运行以下内容时,在内存管理方面是否需要考虑:

public static void main(String[] args) throws NumberFormatException, ParseException, IOException {

    Jedis jedis = new Jedis("<HostName>");

    TimeSeriesPoints retrieved = null;

    while(!finished) {

        try {

            finished = true;

            List<String> keys = getNextFiftyKeys();

            String[] cacheKeys = new String[keys.size()];

            List<String> cacheResults = jedis.mget(keys.toArray(cacheKeys));

            List<TimeSeries> cachedTimeSeries = new ArrayList<TimeSeries>();

            for(String cacheResult : cacheResults){
                try {
                    retrieved = TimeSeriesPoints.parseFrom(cacheResult.getBytes());

                    TimeSeries timeSeries = new TimeSeries(retrieved.getName(), retrieved.getPointsList());

                    cachedTimeSeries.add(timeSeries);
                } 
                catch (InvalidProtocolBufferException e) {
                    e.printStackTrace();
                }
            }

            long pointsCount = 0;
            for(TimeSeries timeSeries : cachedTimeSeries){
                pointsCount += timeSeries.points.length;
            }

            System.out.println("retrieved: " + cachedTimeSeries.size());
            System.out.println("points:" + pointsCount);            
    }
}
publicstaticvoidmain(String[]args)抛出NumberFormatException、ParseException、IOException{
绝地武士=新绝地武士(“”);
检索到的TimeSeriesPoints=null;
当(!完成){
试一试{
完成=正确;
List keys=getNextFiftyKeys();
String[]cacheKeys=新字符串[keys.size()];
List cacheResults=jedis.mget(keys.toArray(cacheKeys));
List cachedTimeSeries=new ArrayList();
for(字符串cacheResult:cacheResults){
试一试{
retrieved=TimeSeriesPoints.parseFrom(cacheResult.getBytes());
TimeSeries TimeSeries=新的TimeSeries(检索到的.getName(),检索到的.getPointsList());
cachedTimeSeries.add(timeSeries);
} 
捕获(无效的RotocolBufferException e){
e、 printStackTrace();
}
}
long pointscont=0;
对于(TimeSeries TimeSeries:cachedTimeSeries){
pointsCount+=timeSeries.points.length;
}
System.out.println(“检索:“+cachedTimeSeries.size());
System.out.println(“点:“+pointscont”);
}
}
TimeSeriesPoints.parseFrom抛出异常,堆栈跟踪如下。不确定确切原因

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.ArrayList.ensureCapacity(Unknown Source)
    at java.util.ArrayList.add(Unknown Source)
    at com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints.<init>(TimeSeriesProtos.java:115)
    at com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints.<init>(TimeSeriesProtos.java:82)
    at com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints$1.parsePartialFrom(TimeSeriesProtos.java:151)
    at com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints$1.parsePartialFrom(TimeSeriesProtos.java:1)
    at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:141)
    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:176)
    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:188)
    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:193)
    at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49)
    at com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints.parseFrom(TimeSeriesProtos.java:958)
    at program.main(program.java:77)
线程“main”java.lang.OutOfMemoryError中的异常:java堆空间 位于java.util.Arrays.copyOf(未知源) 位于java.util.Arrays.copyOf(未知源) 位于java.util.ArrayList.ensureCapacity(未知源) 位于java.util.ArrayList.add(未知源) 在com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints.(TimeSeriesProtos.java:115) 位于com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints。(TimeSeriesProtos.java:82) 在com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints$1.parsePartialFrom(TimeSeriesProtos.java:151)上 在com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints$1.parsePartialFrom(TimeSeriesProtos.java:1) 位于com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:141) 位于com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:176) 位于com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:188) 位于com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:193) 位于com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:49) 位于com.wimiro.caching.TimeSeriesProtos$TimeSeriesPoints.parseFrom(TimeSeriesProtos.java:958) 位于program.main(program.java:77) 这会导致尝试读取800个时间序列(每个都有大约4000个数据点)的失败。因为在本例中,我一次只处理50个时间序列,所以我不希望内存占用显著增加


在.NET中,我做这件事并不困难。那么,是时候学习一些Java了。我需要读些什么?

您正在尝试从Java字符串(UTF-16)中获取字节数组,该字符串是从jedis(使用SafeCoder将UTF-16转换为bytearray)获得的,后者调用redis(C char 8位编码).我认为这是问题的根源,您的java字符串可能不正确,这导致protobuf失败

你应该尝试使用绝地武士的字节数组签名:

final List<byte[]> mget = jedis.mget(byteArray1, byteArray2, ...);
final List mget=jedis.mget(byteArray1,byteArray2,…);

然后尝试在字节数组上使用protobuf。另外,请检查如何使用jedis在redis中插入数据,在所有情况下,建议将字节数组签名与二进制数据一起使用。

protobuf Java不幸地对重复的基元类型使用了非常低效的编码——每个元素都被装箱。例如,a
repeated int32
is表示为
ArrayList
。理论上,这可以在protobuf实现中进行优化,但我知道上一次没有这样做。我猜您的问题就是由此产生的


如果还没有,请尝试增加JVM的最大堆大小(例如2GB的
-Xmx2g

您可以添加TimeSeriesPoints.parseFrom(…)的代码吗?它有漏洞吗?它在protobuf-java2.5.0.jar中。如果这里有漏洞,那将是相当令人惊讶的。jedis.mget返回列表,而问题似乎在于TimeSeriesPoints。parseFrom@ofraski不,mget上存在重载。您可以直接使用ByteArray,从而绕过字符串和字节数据之间的转换错误。