2012-01-17 3 views
13

मेरे पास एक JSON फ़ाइल है जिसमें बहुत सारे टेस्ट डेटा हैं, जिन्हें मैं पार्स करना चाहता हूं और एक एल्गोरिदम के माध्यम से धक्का देना चाहता हूं। यह 60,000 या उससे अधिक तत्वों की सूची के साथ आकार में लगभग 30 एमबी है। मैं शुरू में scala.util.parsing.json में सरल पार्सर की कोशिश की, तो जैसे:net.liftweb.json या scala.util.parsing.json के साथ एक बड़ी (30 एमबी) JSON फ़ाइल को पार्सिंग आउटऑफमेमरी अपवाद देता है। कोई सिफारिशें?

import scala.util.parsing.json.JSON 
val data = JSON.parseFull(Source.fromFile(path) mkString) 

कहाँ पथ सिर्फ एक स्ट्रिंग पथ बड़ा JSON फ़ाइल युक्त है। यही कारण है कि 45 मिनट के लिए दूर chugged, तो यह फेंक दिया: मेरे लिए

java.lang.OutOfMemoryError: GC overhead limit exceeded 

किसी ने तो कहा कि कोई भी इस पुस्तकालय का उपयोग करता है और मैं लिफ्ट के JSON पार्सर का उपयोग करना चाहिए। तो मैं अपने स्काला आरईपीएल में यह करने की कोशिश की:

scala> import scala.io.Source 
import scala.io.Source 

scala> val s = Source.fromFile("path/to/big.json") 
s: scala.io.BufferedSource = non-empty iterator 

scala> val data = parse(s mkString) 
java.lang.OutOfMemoryError: GC overhead limit exceeded 

इस समय यह केवल बारे में 3 मिनट लग गए, लेकिन एक ही त्रुटि।

तो, जाहिर है कि मैं फ़ाइल को छोटे में विभाजित कर सकता हूं, जेएसओएन फाइलों की निर्देशिका पर फिर से चला सकता हूं और अपने डेटा को टुकड़ा-टुकड़ा टुकड़ा कर सकता हूं, लेकिन यदि संभव हो तो मैं इसे टालना चाहूंगा। क्या किसी के पास कोई सिफारिश है?

अधिक जानकारी के लिए - मैं बिना किसी समस्या के क्लोजर (इंकेंटर के साथ विज़ुअलाइज़ेशन के लिए) में पिछले कुछ हफ्तों के साथ इस डेटासेट के साथ काम कर रहा था। निम्नलिखित काम करता है बिल्कुल ठीक:

user=> (use 'clojure.data.json) 
nil 
user=> (use 'clojure.java.io) 
nil 

user=> (time (def data (read-json (reader "path/to/big.json")))) 
"Elapsed time: 19401.629685 msecs" 
#'user/data 

उत्तर

9

उन संदेशों से संकेत मिलता है कि आवेदन कचरा इकट्ठा करने more than 98% of its time खर्च कर रहा है।

मुझे संदेह होगा कि स्कैला बहुत कम अल्पकालिक वस्तुओं का उत्पादन कर रहा है, जो अत्यधिक जीसी पैदा कर रहा है। आप -verbosegc कमांड लाइन स्विच java पर जोड़कर जीसी प्रदर्शन को सत्यापित कर सकते हैं।

जावा पर default max heap size जावा 1.5+ सर्वर वीएम 1 जीबी (या स्थापित स्मृति की 1/4, जो भी कम हो) है, जो आपके उद्देश्यों के लिए पर्याप्त होना चाहिए, लेकिन आप नई पीढ़ी को यह देखने के लिए बढ़ा सकते हैं कि क्या आपके प्रदर्शन में सुधार करता है। ओरेकल वीएम पर, यह -Xmn विकल्प के साथ किया जाता है। निम्न पर्यावरण चर सेट करने का प्रयास करें:

$JAVA_OPTS=-server -Xmx1024m -Xms1024m -Xmn2m -verbosegc -XX:+PrintGCDetails 

और अपना एप्लिकेशन फिर से चलाएं।

आपको विवरण के लिए this tuning guide भी देखना चाहिए।

+0

मैं भाग गया: $ JAVA_OPTS = "- Xmx1024m -Xms1024m -Xmn2m" स्केला -classpath उठा-json_2.9.0-1-2.4.jar: paranamer-2.1.jar समय लगा, लेकिन इस बार मुझे मिल गया: java.lang.OutOfMemoryError: जावा हीप स्पेस मैं ढेर की जगह को बढ़ाने और वापस पोस्ट करने का प्रयास करूंगा। किसी भी मामले में व्यापक उत्तर के लिए धन्यवाद। उपयोगी कड़ियाँ! – jaley

+1

ठीक है!2 जीबी पर ढेर आकार और आपके द्वारा प्रस्तावित अन्य विकल्पों के साथ, यह काम करता है। फ़ाइल को पार्स करने में लगभग 10 मिनट लगते हैं और बहुत सारी मेमोरी का उपयोग करते हैं, जो थोड़ा परेशान है लेकिन इस स्वचालित प्रदर्शन परीक्षण के लिए स्वीकार्य है। आपकी सहायताके लिए धन्यवाद! – jaley

+1

कोई समस्या नहीं है। हालांकि यह प्रदर्शन अबाध है! – Jonathan

3

इसके बजाय Jerkson का उपयोग करने का प्रयास करें। जेर्कसन Jackson का उपयोग करता है, जो बार-बार जेवीएम पर सबसे तेज़ और सबसे मेमोरी कुशल JSON पार्सर के रूप में स्कोर करता है।

मैंने लिफ्ट जेएसओएन और जेर्कसन दोनों उत्पादन में उपयोग किया है, और जेर्कसन का प्रदर्शन लिफ्ट की तुलना में बेहतर रूप से बेहतर था (विशेष रूप से बड़े JSON दस्तावेज़ों को पार्सिंग और उत्पन्न करते समय)।

+1

परियोजना छोड़ दी गई है। विकल्पों की एक महान सूची के लिए यह पोस्ट देखें: http://engineering.ooyala.com/blog/comparing-scala-json- पुस्तकालय – pjvds

संबंधित मुद्दे