De mémoire d'erreur lors de l'analyse d'un grand JSON à l'aide de Jackson bibliothèque sur Android
Je suis à l'aide de Jackson bibliothèque pour analyser une grande réponse JSON à partir du serveur. La taille de l'json est autour de 7 à 8 mo.
Je suis le outOfMemoryError sur ce morceau de code:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootParser = mapper.readValue(is, JsonNode.class);
et c'est l'exception qui je suis:
01-14 13:13:20.103: E/AndroidRuntime(25468): FATAL EXCEPTION: Thread-13
01-14 13:13:20.103: E/AndroidRuntime(25468): java.lang.OutOfMemoryError
01-14 13:13:20.103: E/AndroidRuntime(25468): at java.util.ArrayList.add(ArrayList.java:123)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.node.ArrayNode._add(ArrayNode.java:722)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.node.ArrayNode.add(ArrayNode.java:203)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeArray(JsonNodeDeserializer.java:224)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:200)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeArray(JsonNodeDeserializer.java:224)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:200)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeArray(JsonNodeDeserializer.java:224)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:200)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:197)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeArray(JsonNodeDeserializer.java:224)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:200)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.BaseNodeDeserializer.deserializeObject(JsonNodeDeserializer.java:197)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:58)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:15)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
01-14 13:13:20.103: E/AndroidRuntime(25468): at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1909)
01-14 13:13:20.103: E/AndroidRuntime(25468): at com.sarla.smartglance.communication.JsonDecoder.decodeResponse(JsonDecoder.java:87)
01-14 13:13:20.103: E/AndroidRuntime(25468): at com.sarla.smartglance.communication.JsonDecoder.decode(JsonDecoder.java:68)
01-14 13:13:20.103: E/AndroidRuntime(25468): at com.sarla.smartglance.communication.MHttpManager$1.run(MHttpManager.java:86)
J'ai tout essayé mais impossible de trouver une quelconque solution à analyser de telles une grande quantité de données sur android.
Avez-vous essayé d'utiliser
Donner gson un aller.
Quelle est la taille des données sur la liste de tableaux, de sons, de vraiment grand.
Gson ne va pas aider -- modèle d'arbre est lourd et environ la même taille sur les différentes libs.
.readTree()
à la place de la lecture dans un JsonNode
?Donner gson un aller.
Quelle est la taille des données sur la liste de tableaux, de sons, de vraiment grand.
Gson ne va pas aider -- modèle d'arbre est lourd et environ la même taille sur les différentes libs.
OriginalL'auteur Ramit | 2013-01-14
Vous devez vous connecter pour publier un commentaire.
Avec 7 à 8 mégas de JSON, modèle d'arbre que vous utilisez généralement recours au 20 - 50 mégas de mémoire (dom modèles sont de 3 à 5 fois plus grande, à la fois pour XML et JSON). Il n'y a pas beaucoup que vous pouvez faire à ce sujet, indépendamment de bibliothèque utilisée: ils ont tous construire des arbres à l'aide de
List
s etMap
s, ce qui est un lourd poids moyen de le faire.Au lieu de cela, vous devriez considérer l'utilisation de Plain Old Java Objects (Pojo), qui va l'utiliser beaucoup moins de mémoire. Pour cela, vous devez le modèle POJO qui correspond à votre structure JSON; sans connaître la structure, je ne peux pas donner un exemple (si vous ajoutez un exemple sur la question, je peux), mais le code à analyser est similaire à GSON code référencée par une autre réponse:
Cela fonctionne sur Jackson, ainsi que de nombreux autres Java JSON libs (Gson, Genson au moins), et sera aussi plus rapide de la méthode à utiliser. JSON arbres sont par nature coûteux et lourds de poids, et ne pas être utilisé pour le multi-megatbyte contenu.
Enfin, si votre entrée est constitué d'une séquence d'éléments, il y a de meilleures façons de tranche (ce qui peut être fait indépendamment du fait que des éléments individuels serait
JsonNode
s ou Pojo!). Mais je ne sais pas si votre contenu est comme ça.Merci beaucoup StaxMan.. je l'ai fait remarquer qu'il a consommé de 20 à 30 MO de mémoire, mais il n'y a rien que je puisse faire pour le réduire. Pour POJO de base du modèle, j'ai du changer toute la structure de l'analyse. Mon entrée est un peu complexe car il est une analyse de données. Donc, si c'est le seul moyen alors je suppose que je dois aller avec qui.
Une autre possibilité est que si (et seulement si) la partie du modèle est une séquence (Liste/Tableau) des choses, vous pouvez utiliser des différentiels d'analyse aussi. Si donc, soit il faut utiliser
ObjectMapper.readValues()
ou raw Streaming API (JsonParser
) pour l'itération, puisreadValueAs()
lorsqu'il se trouve à la racine du sous-temps.OriginalL'auteur StaxMan
Nous utilisons ici le gson lib, et avec le code ci-dessus, nous pouvons obtenir des fichiers de taille supérieure à 50 mo sans problème:
Essayer cette lib, c'est un bon, avec les jackson nous n'utilisons que du côté serveur, parce que jackson est plus lente dans l'Android de gson, au moins dans notre test.
FileReader
, il en sera probablement barf sur la non-entrée ASCII. Mais il ne sera pas nécessaire de construire unReader, just pass in
InputStream`.Aussi, des liens vers des test de performance serait génial, c'est la seule fréquemment cité (martinadamek.com/2011/02/04/...) ne montre pas de Gson que plus rapide. Gson n'ont temps de démarrage plus rapide, cependant; et la version 2.1 est ok (les versions antérieures ont été très lent).
Eh bien, ce n'est pas buggé, ça marche très bien pour moi, j'avais des caractères spéciaux sans problème. Le "caminho_arquivo" est l'emplacement du fichier dans la carte sd. - Je l'utiliser parce que je reçois un fichier zippé du serveur, une fois que j'ai dézipper le fichier et obtenir le .fichier json...
Et avec Jackson ne pas m'aider quand j'ai besoin d'analyser des fichiers volumineux, donc pour mon application GSON était le meilleur, encore plus lent, peut lire des fichiers volumineux.
Il peut travailler sur votre plate-forme; mais il peut facilement échouer sur les autres; par conséquent, il est cassé. Vous devez simplement spécifier l'encodage (UTF-8). C'est une erreur commune faite par les développeurs Java, donc peut-être que vous venez de couper / collé de quelque part. N'a pas été conçu comme une insulte, bien que la formulation peut avoir été forte.
OriginalL'auteur William Bertan
Essayer de l'utiliser:
à la place.
OriginalL'auteur fge