PDA

View Full Version : خطا در eclipse هنگام پردازش حجم زیاد داده - GC overhead limit exceeded



a.ahp89
شنبه 07 شهریور 1394, 20:10 عصر
سلام دوستان

من یه فایل به حجم حدودا ۹۰۰ مگابایت رو میخام بخونم و هنگام خوندم رویه هر خطش پردازش انجام بدم و تبدیل به دوقسمتش کنم
وقتی داره فایل رو میخونه خطای زیر رو میده
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at sun.misc.FloatingDecimal.readJavaFormatString(Floa tingDecimal.java:1067)
at java.lang.Double.valueOf(Double.java:504)

یه سرچی زدم گفته بودن فایل ecplise.ini رو دستکاری کن و دوسه تا متغیراشو عوض کن منم اینکارو کردم که اینجوری تغییر دادم
-XX:MaxPermSize=2048m
-Xms2048m
-Xmx4096m


ولی بازم خطا میده.کسی تجربه ای داره تو این زمینه؟

پیشاپیش ممنون از کمکتون.

ahmad.mo74
یک شنبه 08 شهریور 1394, 14:43 عصر
سلام، کدت رو میذاشتی بهتر میشد فهمید مشکل از کجاست.
احتمالا کل فایل رو لود کردی بعد خوندیش.

برای اینکه همچین مشکلی پیش نیاد باید فایل بافر بشه. مثلا از BufferedReader استفاده کن.


void readLines(String source, Consumer<String> action) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(source))) {
String line;
while ((line = reader.readLine()) != null) {
action.accept(line);
}
}
}


یا اینکه با NIO :


void readLines(String source, Consumer<String> action) throws IOException {
Files.readAllLines(Paths.get(source)).forEach(acti on);
}


اگر فایلت خیلی بزرگه از MappedByteBuffer هم میتونی استفاده کنی که مخصوص همینکاره.


import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;


/**
* @author ahmad
*/
public final class LineReader {


private static final int BUFFER_SIZE = 8192;
private static final String LF = "\n";
private static final char CR_CHAR = '\r';


private final List<LineProcessor> processors = new CopyOnWriteArrayList<>();


public void read(String source) throws IOException {
try (FileChannel inChannel = FileChannel.open(Paths.get(source), StandardOpenOption.READ)) {
MappedByteBuffer mbb = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
int count, lineNumber = 0;
StringBuilder sb = new StringBuilder();
byte[] bytes = new byte[BUFFER_SIZE];
while ((count = Math.min(mbb.remaining(), BUFFER_SIZE)) > 0) {
mbb.get(bytes, 0, count);
sb.append(new String(bytes, 0, count, StandardCharsets.UTF_8));
int index;
if ((index = sb.indexOf(LF, 0)) > 0) {
int nextChar = 0;
do {
if (sb.charAt(index - 1) == CR_CHAR) {
fireNextLine(++lineNumber, sb.substring(nextChar, index - 1));
} else {
fireNextLine(++lineNumber, sb.substring(nextChar, index));
}
nextChar = index + 1;
} while ((index = sb.indexOf(LF, nextChar)) > 0);
sb.delete(0, nextChar);
}
}
if (sb.length() > 0) {
fireNextLine(++lineNumber, sb.toString());
}
}
}


public void addLineProcessor(LineProcessor processor) {
processors.add(processor);
}


public void removeLineProcessor(LineProcessor processor) {
processors.remove(processor);
}


private void fireNextLine(int lineNumber, String line) {
for (LineProcessor processor : processors) {
processor.nextLine(lineNumber, line);
}
}


}



public interface LineProcessor {


void nextLine(int lineNumber, String line);


}


تست :

روی فایل 1 گیگی تست کردم. (هر خط 255 کاراکتر)


public static void main(String[] args) throws IOException {
String source = "fileName";
LineReader reader = new LineReader();


//warm up
for (int i = 0; i < 100; i++) {
reader.read(source);
}


AtomicInteger lines = new AtomicInteger(0), totalLength = new AtomicInteger(0);
reader.addLineProcessor((lineNumber, line) -> {
// System.out.printf("%2d %s%n", lineNumber, line);
lines.set(lineNumber);
totalLength.addAndGet(line.length());
});


long start = System.currentTimeMillis();
reader.read(source);
long end = System.currentTimeMillis();


System.out.printf("Number of lines = %d, Total characters = %d%nExecution time = %d ms", lines.get(), totalLength.get(), end - start);
}


خروجی :


Number of lines = 4500000, Total characters = 1147500000
Execution time = 1571 ms

a.ahp89
سه شنبه 10 شهریور 1394, 17:25 عصر
ممنون دوست عزیز بابت مطالب آموزندت
مشکلم اینجوری رفع شد
مسیر زیر رو دنبال:
Run->Run Configurations-> Arguments->VM arguments
و عبارت زیر رو تایپ کنید:
Xmx2048M-

ولی حالا یه سوال

چرا از فایل eclipse.ini نخونده؟

ممنونم.

ahmad.mo74
سه شنبه 10 شهریور 1394, 19:48 عصر
ممنون دوست عزیز بابت مطالب آموزندت


خواهش میکنم.



مشکلم اینجوری رفع شد

مسیر زیر رو دنبال:


Run->Run Configurations-> Arguments->VM arguments


و عبارت زیر رو تایپ کنید:


Xmx2048M-


اینطوری به جای حل مسئله، صورت مسئله رو پاک رو کردی.
کدت رو میزاشتی معلوم میشد مشکل کجاست.



ولی حالا یه سوال



چرا از فایل eclipse.ini نخونده؟



احتمالا اون برای خود eclipse عه و برای پروژه باید از تو همونجایی که گفتی پارامترا ست بشه.

https://wiki.eclipse.org/Eclipse.ini

a.ahp89
سه شنبه 10 شهریور 1394, 22:21 عصر
خواهش میکنم.



اینطوری به جای حل مسئله، صورت مسئله رو پاک رو کردی.
کدت رو میزاشتی معلوم میشد مشکل کجاست.



احتمالا اون برای خود eclipse عه و برای پروژه باید از تو همونجایی که گفتی پارامترا ست بشه.

https://wiki.eclipse.org/Eclipse.ini

مشکل کدم رو فهمیدم , من با scanner فایل رو میخوندم که عوضش کردم از بافر استفاده کردم , دست شد!

بازم سپاس فراوان.