का उपयोग कर डेटा की बड़ी मात्रा में पढ़ने पर मुझे डेटाबेस से बड़ी मात्रा में डेटा निर्यात करने की आवश्यकता है। यहाँ वर्गों है मेरी डेटा का प्रतिनिधित्व करता है कि:आउटऑफमेमरी हाइबरनेट
public class Product{
...
@OneToMany
@JoinColumn(name = "product_id")
@Cascade({SAVE_UPDATE, DELETE_ORPHAN})
List<ProductHtmlSource> htmlSources = new ArrayList<ProductHtmlSource>();
... }
ProductHtmlSource
- बड़ा स्ट्रिंग जो अंदर मैं वास्तव में निर्यात करने के लिए आवश्यकता होती है।
चूंकि निर्यात किए गए डेटा का आकार JVM मेमोरी से बड़ा है, इसलिए मैं अपने डेटा को टुकड़ों से पढ़ रहा हूं। इस तरह:
final int batchSize = 1000;
for (int i = 0; i < 50; i++) {
ScrollableResults iterator = getProductIterator(batchSize * i, batchSize * (i + 1));
while (iterator.getScrollableResults().next()) {
Product product = (Product) iterator.getScrollableResults().get(0);
List<String> htmls = product.getHtmlSources();
<some processing>
}
}
getProductIterator
का कोड:
public ScrollableResults getProductIterator(int offset, int limit) {
Session session = getSession(true);
session.setCacheMode(CacheMode.IGNORE);
ScrollableResults iterator = session
.createCriteria(Product.class)
.add(Restrictions.eq("status", Product.Status.DONE))
.setFirstResult(offset)
.setMaxResults(limit)
.scroll(ScrollMode.FORWARD_ONLY);
session.flush();
session.clear();
return iterator;
}
समस्या यह है कि मैं एक डेटा हिस्सा के Product
वस्तुओं को पढ़ने के बाद सत्र को साफ करने के बावजूद कहीं जम जाता है और मैं कर रहा हूँ OutOfMemory अपवाद प्राप्त करें। समस्या कोड के ब्लॉक को संसाधित करने में भी नहीं है, इसके बावजूद मुझे स्मृति त्रुटि मिलती है। बैच का आकार भी एक समस्या नहीं है क्योंकि 1000 ऑब्जेक्ट्स आसानी से स्मृति में बैठते हैं।
प्रोफाइलर ने दिखाया कि वस्तुओं org.hibernate.engine.StatefulPersistenceContext
कक्षा में जमा हो जाती है।
स्टैकट्रेस:
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:99)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:518)
at java.lang.StringBuffer.append(StringBuffer.java:307)
at org.hibernate.type.TextType.get(TextType.java:41)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:163)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:154)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:81)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2101)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1380)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1308)
at org.hibernate.loader.Loader.getRow(Loader.java:1206)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:580)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:63)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:109)
at org.hibernate.collection.PersistentBag.size(PersistentBag.java:225)
**at com.rivalwatch.plum.model.Product.getHtmlSource(Product.java:76)
at com.rivalwatch.plum.model.Product.getHtmlSourceText(Product.java:80)
at com.rivalwatch.plum.readers.AbstractDataReader.getData(AbstractDataReader.java:64)**
पोस्ट किया गया stacktrace लेकिन मुझे नहीं लगता कि जीसी की ट्यूनिंग मदद करेगा। मैंने System.gc() की कोशिश की; नए बैच पढ़ने से पहले स्मृति अभी भी बहती है। – Vladimir