으헝헝헝헝헝 ㅠㅠㅠㅠㅠㅠ <div>정말 프게에서 많은 도움을 받았습니다. ㅠㅠㅠㅠㅠ</div> <div>글이 워낙 여러개이고 뒤로 밀린터라...</div> <div>결과 보고는 드려야 할 것 같아서요....</div> <div><br></div> <div>1. 프로그램의 목적</div> <div> - HTTP를 통해 제공되는 JSON 데이터를 가져와서 가공후 DB에 저장한다.</div> <div><br></div> <div>2. 여러가지 사항들</div> <div> - 구동 환경은 centos</div> <div> - 컴파일러는 gcc</div> <div> - C 언어</div> <div> - mysql</div> <div> - 반복 작업을 무한히 해야하며 빠를 수록 좋지만 상한선은 1초당 20회. (json 데이터 제공측 제한)</div> <div><br></div> <div>3. 사용된 라이브러리</div> <div> - curl (<a target="_blank" href="http://curl.haxx.se/" target="_blank">http://curl.haxx.se/</a>)</div> <div> - json-c (<a target="_blank" href="https://linuxprograms.wordpress.com/2010/05/20/json-c-libjson-tutorial/" target="_blank">https://linuxprograms.wordpress.com/2010/05/20/json-c-libjson-tutorial/</a>)</div> <div> - mysql</div> <div><br></div> <div>4. 프로그램 구동 순서</div> <div>1) curl을 이용하여 웹 데이터를 가져온다.</div> <div>2) 가져온 데이터를 json object로 만든다.</div> <div>3) 데이터를 처리한다.</div> <div>4) db에 입력한다.</div> <div><br></div> <div><br></div> <div>5. 대략적인 코드 구성</div> <div>main(){</div> <div>변수 선언</div> <div><br></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>for{</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>curl에서 데이터 가져옮</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>json object로 만듦</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>데이터 처리</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>(일부)</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>for{</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>데이터 처리</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>db 입력</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>}</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>db 입력</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>}</div> <div><br></div> <div>mysql_close()</div> <div>}</div> <div><br></div> <div>--> 함수 없음. 그냥 main에서 통짜로 실행</div> <div><br></div> <div><br></div> <div>6. 문제 발생</div> <div>- 1차 메모리 누수 ( 반복문 1건당 메모리 사용량 0.5%씩 상승 )</div> <div>멍청하게도 모든 변수에 대해 메모리 반환을 하지 않음으로 발생.</div> <div>동적 할당으로 선언했던 변수들을 free 로 반환.</div> <div><br></div> <div><br></div> <div>- 2차 메모리 누수 ( 반복문 1건당 메모리 사용량 0.4%씩 상승 )</div> <div>그럼에도 불구하고 메모리 누수가 발생함.</div> <div>동적할당 했던 변수들을 전부 없애고 고정으로 변경.</div> <div>추가로 찾아보니</div> <div>json object 로 선언된 변수들을 초기화(?) 해주는 함수를 써줘야 한다고 함.</div> <div><span style="font-size:9pt;line-height:1.5;">전체 for문 하단에 다음과 같이 추가</span></div> <div><br></div> <div>if (!jobj){ json_object_put(jobj); }</div> <div><br></div> <div><br></div> <div>- 3차 메모리 누수 ( 반복문 100건당 메모리 사용량 0.1%씩 상승 )</div> <div>그럼에도 불구하고 매번 반복문이 반복될때마다 계속해서 메모리 누수 발생.</div> <div>찾아보니 curl에도 메모리 누수가 있다고 함.</div> <div><br></div> <div><div>curl_easy_cleanup(curl);</div> <div>curl_global_cleanup();</div> <div>free(resData.response); // url에서 가져온 데이터를 보관하는 변수. 데이터 크기에 따라 동적할당을 하므로 free로 반환해야함.</div></div> <div><br></div> <div><br></div> <div>- 4차 메모리 누수 ( 반복문 100건당 메모리 사용량 0.1%씩 상승 )</div> <div>아직도 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ .. ㅋㅋㅋ.ㅋ.ㅋㅋㅋㅋㅋㅋㅋㅋ............</div> <div>이때부터 혹시나 하는 마음에 mysql 관련 함수들에도 메모리 누수가 있나 확인해보았으나 없음.</div> <div><span style="font-size:9pt;line-height:1.5;">오유에서 도움을 받아 valgrind 로 검사를 해보니, 여전히 curl 에서 문제가 있다고 나옴.</span></div> <div><br></div> <div>더 구글링 해봐도 정답이 없길래.....</div> <div>게으름 부리지 말고 작업들을 함수로 따로 만들기로 함.</div> <div>함수 작동이 끝나면 사용했던 메모리는 전부 반환하겠지 뭐! <-- 라는 생각..</div> <div><br></div> <div>char* get_json(char *url) {</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>인자로 넘어온 url에서 데이터를 가져오는 작업</div> <div>}</div> <div><br></div> <div><br></div> <div>- 5차 메모리 누수 ( 반복문 1000건당 메모리 사용량 0.1%씩 상승 )</div> <div>ㅋㅋㅋ......</div> <div>이때 오유에서 아예 고정 길이로 데이터를 받아버리라는 조언을 얻음.</div> <div>그렇게 코드를 변경 했음에도 (char test[35000];) 여전히 메모리 누수가 발생함.</div> <div><br></div> <div><br></div> <div>- 6차 메모리 누수 ( 반복문 1000건당 메모리 사용량 0.1%씩 상승 )</div> <div>차근차근 다시 생각을 해봤는데, 아주 중요한 문제가 있었음.</div> <div>새롭게 만든 get_json() 함수에서... 이런 멍청한 부분이 있음.</div> <div><br></div> <div>char* get_json(){</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>데이터 처리</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>data = malloc(siezeof(char)*size);</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>return data;</div> <div>}</div> <div><br></div> <div>!?</div> <div><br></div> <div>그렇다고 free(data)를 한 후 return data; 를 할수는 없었기에 머리가 아파짐.</div> <div><br></div> <div>ㅁㄴ이ㅏ러니ㅏㅇ러니아러미낭러민아럼ㄴ이라ㅓㅁ닝러</div> <div><br></div> <div>어떻게 해야할까...........</div> <div><br></div> <div>생각하다가...</div> <div><br></div> <div>한번도 안해본건데.... 왠지 될거 같다는 생각으로 이렇게 바꿈.</div> <div><br></div> <div><br></div> <div>void get_json(char *url, char **data){</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>데이터 처리</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>*data = malloc(sizeof(char) * size+1);</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>strcpy(data, 처리된데이터);</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>return data;</div> <div>}</div> <div><br></div> <div>void main(){</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>char *data;</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span></div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>get_json(url, &data);</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>jobj = json_tokener_parse(data); // json 으로 파싱</div> <div><span class="Apple-tab-span" style="white-space:pre;"> </span>free(data);</div> <div>}</div> <div><br></div> <div>-> 데이터를 리턴시킬 문자열 변수를 main에서 선언하고 그 주소를 인자로 넘긴 후,</div> <div>get_json함수에서 데이터 길이에 따라 동적 할당을 해주고 데이터 복사 후 함수 종료.</div> <div><br></div> <div>-> 데이터가 리턴 되었으므로 json object를 만든 다음 바로 free로 메모리 반환.</div> <div><br></div> <div>7. 결과</div> <div>프로그램 실행시 메모리 점유율 0.8%</div> <div><span style="font-size:9pt;line-height:1.5;">10만건을 반복 후 메모리 점유율 0.8%</span></div> <div><span style="font-size:9pt;line-height:1.5;"><br></span></div> <div><img src="http://down.humoruniv.org/hwiparambbs/data/thema2/hu_1419521607_8116879720.jpg" alt=""></div> <div><br></div> <div><br></div> <div>도움을 주신 오유 프게 분들께 감사드립니다. (__);</div> <div>이제 이걸 멀티 쓰레드로 해보는걸 한번 도전해보려구요 ^-^ 아이고 좋다....</div>