2015-10-08 53 views
1

我正在使用GSON Stream API将大量对象转换为json。该列表包含110.000个对象。我用这个代码:OutOfMemoryError当使用GSON将对象转换为json时

public static void cacheToFile() { 

    Gson gson = new GsonBuilder() 
       .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 
       .registerTypeAdapter(Date.class, new DateTypeAdapter()) 
       .create(); 

    try { 

     JsonWriter writer = new JsonWriter(new FileWriter(Functions.getAppSupportPath()+"cache.json")); 
     writer.beginArray(); 

     int i = 1; 
     synchronized(cache) { 

      for (CachedObject<?> object : cache) { 
       gson.toJson(object, CachedObject.class, writer); 
       System.out.println(i); 
       i++; 
      } 

     } 

     writer.endArray(); 
     writer.close(); 

    } 
    catch (Exception e) { 
     Functions.createExceptionDialog(e); 
    } 

} 

循环达到55.000然后冻结一段时间。之后,它会抛出以下错误:

java.lang.OutOfMemoryError: GC overhead limit exceeded 
at com.google.gson.internal.$Gson$Types$WildcardTypeImpl.getUpperBounds($Gson$Types.java:556) 
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:373) 
at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:376) 
... 

我认为Stream API可以防止内存问题,但在这种情况下,它不会。如何将对象列表转换为json,从而防止此问题?

任何帮助,非常感谢!

回答

0

你的looop冻结然后崩溃的原因是GC试图释放足够的内存来继续计算,但它无法做到。这可能是由于同时将太多元素保存在内存中造成的。解决这个问题的唯一方法是增加为JVM分配的内存或通过重构代码来减少内存复杂性。

如果可以包含完整的堆栈跟踪,可能会有所帮助。

+0

感谢您的回答!我知道错误的含义,但我不明白它为什么会被抛出。我认为GSON Stream API可以防止这种情况发生。堆栈跟踪的其余部分是没有用的,它只是重复最后两行。 – bashoogzaad

+0

堆栈跟踪将有助于了解您的代码在哪一点破坏。我会假设它发生在'gson.toJson(object,CachedObject.class,writer)',但我无法知道 – vivianig

相关问题