hadoop中明显的内存泄漏(Apparent memory-leak in hadoop)
我正在运行的hadoop程序中有明显的内存泄漏。 具体来说,我收到消息:超出了ERROR GC开销限制,之后是异常
attempt_201210041336_0765_m_0000000_1: Exception in thread "Tread for syncLogs" java.lang.OutOfMemoryError: GC overhead limit exceeded attempt_201210041336_0765_m_0000000_1: at java.util.Vector.elements (Vector.java:292) attempt_201210041336_0765_m_0000000_1: at org.apache.log4j.helpers.AppenderAtachableImpl.getAllAppenders(AppenderAttachableImpl.java:84 attempt_201210041336_0765_m_0000000_1: at org.apache.log4j.Category.getAllAppenders (Category.java:415) attempt_201210041336_0765_m_0000000_1: at org.apache.hadoop.mapred.TaskLog.syncLogs(TaskLog.java:256) attempt_201210041336_0765_m_0000000_1: at org.apache.hadoop.mapred.Child$3.run(Child.java:157)
我正在运行初始试验中应该是非常小的数据集,所以我不应该达到任何内存限制。 更重要的是,我不想改变hadoop配置; 如果程序无法使用当前配置运行,则需要重写程序。
任何人都可以帮我弄清楚如何诊断这个问题? 是否有一个命令行参数来获取内存使用的堆栈跟踪? 跟踪此问题的任何其他方式?
PS。 我手工编写了错误信息,无法从有问题的系统中复制粘贴。 所以请忽略任何错字作为我的愚蠢错误。
编辑:更新到此。 我再跑几次了; 虽然我总是得到错误GC开销限制超过消息我不总是得到log4j的堆栈跟踪。 所以问题可能不是log4j,而是log4j碰巧由于缺少内存而导致失败......其他的东西?
I have an apparent memory leak in a hadoop program I'm running. Specifically I get the message: ERROR GC overhead limit exceeded followed later by the exception
attempt_201210041336_0765_m_0000000_1: Exception in thread "Tread for syncLogs" java.lang.OutOfMemoryError: GC overhead limit exceeded attempt_201210041336_0765_m_0000000_1: at java.util.Vector.elements (Vector.java:292) attempt_201210041336_0765_m_0000000_1: at org.apache.log4j.helpers.AppenderAtachableImpl.getAllAppenders(AppenderAttachableImpl.java:84 attempt_201210041336_0765_m_0000000_1: at org.apache.log4j.Category.getAllAppenders (Category.java:415) attempt_201210041336_0765_m_0000000_1: at org.apache.hadoop.mapred.TaskLog.syncLogs(TaskLog.java:256) attempt_201210041336_0765_m_0000000_1: at org.apache.hadoop.mapred.Child$3.run(Child.java:157)
I'm running on what should be very small data sets in an initial trial, so I shouldn't be hitting any memory limit. More to the point I don't want to change the hadoop configuration; if the program can't run with the current configuration the program needs rewritten.
Can anyone help me figure out how to diagnose this issue? ise there a command line argument to get a stack trace of memory usage? any other way of tracking this issue?
ps. I wrote the error message by hand, can't copy-paste from the system that has the issue. So please ignore any typo as being my stupid fault.
edit: update to this. I ran the job a few more times; while I always get the Error GC overhead limit exceeded message I don't always get the stacktrace for log4j. So the issue is probably not log4j, instead log4j happened to fail due to the lack of memory caused by...something else?
原文:https://stackoverflow.com/questions/13647277
最满意答案
唯一可以确定的方法是做一个循环; 一次读一个字符并存储。 如果您分配的缓冲区已满,请将其增加一些适当的数量(建议一次超过一个字节用于性能,经典的经验法则是将其加倍)。
当你考虑字符串结束时停止,可能是换行或EOF。
The only way to be sure is to do a loop; read one character at a time and store. If your allocated buffer becomes full, grow it by some suitable amount (more than one byte at a time is recommended for performance, a classic rule-of-thumb is to double it).
Stop when you consider the string to end, perhaps at line feed or EOF.
相关问答
更多-
您在每个输入字符之后在process.stdin上附加一个readable侦听器,这会导致每个字符调用process.stdin.read()多次。 stream.Readable.read() ,其process.stdin是一个实例,如果输入缓冲区中没有数据,则返回null。 要解决此问题,请将侦听器附加一次。 process.stdin.setRawMode(true); process.stdin.on('readable', function () { var key = String(pro ...
-
你可以让getline为你分配内存(这是使用标准fgets函数的非标准getline函数的关键 )。 从getline手册页面: 如果*lineptr为NULL ,则getline()将分配一个用于存储行的缓冲区,该行应由用户程序释放。 ( *n的值被忽略。) 或者,在调用getline()之前, *lineptr可以包含指向malloc分配的缓冲区的指针*n个字节的大小。 如果缓冲区不足以容纳该行,则getline()使用realloc调整它的大小,并根据需要更新*lineptr和*n 。 所以你可以这样 ...
-
C - fgets从stdin读取行,最大长度为1024?(C - fgets read line from stdin, maximum length is 1024? [duplicate])[2022-04-05]
代码本身没有任何问题。 问题是终端驱动程序在其缓冲区中的限制为1 KiB,因此您输入的内容不能超过1023个字符加上换行符。 大多数系统都有类似的限制。 从历史上看,限制要小得多,比如256字节。 There's nothing wrong with the code per se. The problem is the terminal driver which has a limit of 1 KiB in its buffer, so you can't input more than the 102 ... -
尝试这个 #include
#include #include #define DEFAULT_INPUT_LENGTH 20 char * readMessage(FILE* file); void writeChar(char* string, char c); int main(void){ printf("Message:\n"); char * msg = readMessage(stdin); pri ... -
一种策略是检查字符串是否存在换行符; 如果找不到,那么您的用户可能输入的字符串对于目标缓冲区来说太长了。 在这种情况下,您可以使用第二个虚拟缓冲区作为目标重复调用fgets()并丢弃虚假输入: if (fgets(str, STR_SIZE, stdin) != NULL) { char *nl = strchr(str, '\n'); if (nl == NULL) { /** * Newline not found, input string too long for ta ...
-
唯一可以确定的方法是做一个循环; 一次读一个字符并存储。 如果您分配的缓冲区已满,请将其增加一些适当的数量(建议一次超过一个字节用于性能,经典的经验法则是将其加倍)。 当你考虑字符串结束时停止,可能是换行或EOF。 The only way to be sure is to do a loop; read one character at a time and store. If your allocated buffer becomes full, grow it by some suitable amo ...
-
从C ++中的stdin读取长度大于4096字节的字符串(Read a string of length greater than 4096 bytes from stdin in C++)[2022-03-17]
根据您发布的内容使用此测试程序: #include#include int main() { std::string a; std::cin >> a; std::cout << a.length() << std::endl; } 我可以: ./a.out < fact100000.txt 并得到输出: 456574 但是,如果我将'n'paste从编辑器复制到控制台,它会在4095处停止。我希望在游戏机拷贝'n'的处理中有一 ... -
试试这个.. #include
int main(){ char next; while((next=getchar())!=EOF) printf("%c\n",next); } 然后查看getchar()的手册页以查看真实情况。 Try running this.. #include int main(){ char next; while((next=getchar())!=EOF) pri ... -
删除呼叫 in.close(); 当您关闭in ,您还close System.in全局(并且它不会重新打开)。 public void readInt() { Scanner in = new Scanner(System.in); System.out.println("Please type in an integer"); int length = in.nextInt(); System.out.println("Integer you type is: " + ...
-
来自MSDN : .NET Framework使用UTF-16编码(由UnicodeEncoding类表示)来表示字符和字符串 所以a1.Length是UTF-16代码单元( 字符,代码点,字形和字形之间有什么区别? )。 在基本BMP(基本多语言平面)中的西里尔字符都使用单个代码单元(因此单个char )。 例如,许多表情符号使用两个代码单元(两个char ,4个字节!)......它们不在BMP中。 例如,请参阅https://ideone.com/ASDORp 。 如果你想要大小IN BYTES, a ...