2012-12-20 2 views
9

아무 것도하지 않는 서버로 nodejs v8 메모리를 프로파일하려고합니다. node-memwatch를 사용하여 heap diff를 얻었습니다. 연결하기 전에 힙 정보를 수집하고 연결이 끊어진 후. 나는 node-memwatch를 사용했다. 클라이언트 측에서 200 개의 동시 연결을 시도했습니다.nodejs v8 메모리 gc 할당 실패

다음은 연결이 끊어진 후의 gc 추적입니다.

누구든지 나를 이해할 수 있습니다.

1. 왜 메모리가 증가하고 있습니까? 연결이 끊어진 후 서버는 절대 아무 것도하지 않습니다. 수집되는 쓰레기로 항상 떨어지지 않아야합니까?
2. 할당 실패 란 무엇입니까? 여기 어떻게 추적을 해석합니까?

15802 ms: Mark-sweep 8.9 (45.0) -> 8.1 (45.0) MB, 58 ms [allocation failure] [GC in old space forced by flags]. 
16144 ms: Mark-sweep 9.2 (45.0) -> 8.4 (45.0) MB, 53 ms [allocation failure] [GC in old space forced by flags]. 
16495 ms: Mark-sweep 9.5 (45.0) -> 8.7 (46.0) MB, 60 ms [allocation failure] [GC in old space forced by flags]. 
16837 ms: Mark-sweep 9.8 (46.0) -> 9.0 (46.0) MB, 56 ms [allocation failure] [GC in old space forced by flags]. 
17197 ms: Mark-sweep 10.1 (46.0) -> 9.4 (46.0) MB, 62 ms [allocation failure] [GC in old space forced by flags]. 
17905 ms: Mark-sweep 11.5 (46.0) -> 10.0 (47.0) MB, 74 ms [Runtime::PerformGC] [GC in old space forced by flags].                
18596 ms: Mark-sweep 12.2 (47.0) -> 10.7 (47.0) MB, 75 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
19315 ms: Mark-sweep 12.8 (47.0) -> 11.3 (48.0) MB, 83 ms [allocation failure] [GC in old space forced by flags]. 
20035 ms: Mark-sweep 13.4 (48.0) -> 12.0 (49.0) MB, 90 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
21487 ms: Mark-sweep 16.0 (49.0) -> 13.2 (50.0) MB, 96 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
22950 ms: Mark-sweep 17.3 (50.0) -> 14.5 (52.0) MB, 116 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
24376 ms: Mark-sweep 18.8 (52.0) -> 15.9 (53.0) MB, 114 ms [allocation failure] [GC in old space forced by flags]. 
25849 ms: Mark-sweep 19.9 (53.0) -> 17.2 (54.0) MB, 129 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
28773 ms: Mark-sweep 25.2 (54.0) -> 19.7 (57.0) MB, 149 ms [allocation failure] [GC in old space forced by flags]. 
31725 ms: Mark-sweep 27.7 (57.0) -> 22.2 (59.0) MB, 172 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
34678 ms: Mark-sweep 30.2 (59.0) -> 24.7 (61.0) MB, 190 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
44045 ms: Mark-sweep 28.4 (61.0) -> 25.8 (63.0) MB, 180 ms [idle notification] [GC in old space forced by flags]. 
44216 ms: Mark-sweep 25.8 (63.0) -> 25.8 (63.0) MB, 170 ms [idle notification] [GC in old space requested]. 
57471 ms: Mark-sweep 26.9 (63.0) -> 25.8 (62.0) MB, 167 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
57651 ms: Mark-sweep 26.8 (62.0) -> 25.5 (62.0) MB, 160 ms [Runtime::PerformGC] [GC in old space forced by flags]. 
57828 ms: Mark-sweep 26.5 (62.0) -> 25.5 (62.0) MB, 159 ms [Runtime::PerformGC] [GC in old space forced by flags]. 

덕분에,

답변

1

참조 :

PrintF("%s %.1f (%.1f) -> %.1f (%.1f) MB, ", 
     CollectorString(), 
     static_cast<double>(start_object_size_)/MB,                      
     static_cast<double>(start_memory_size_)/MB, 
     SizeOfHeapObjects(), 
     end_memory_size_mb); 

를 GC가 시작될 때 각 라인은 하나의 GC입니다

start_object_size_ = heap_->SizeOfObjects(); 

GC의 요약 : 왜 start_object_size_의로

PrintF("total_size_before=%" V8_PTR_PREFIX "d ", start_object_size_);                 
PrintF("total_size_after=%" V8_PTR_PREFIX "d ", heap_->SizeOfObjects()); 

을 시간이 증가 내 애플 리케이션이 유휴 상태 일 때, 나는 아마도 GC 중에 추측하고 있는데, 어떤 객체는 프로가된다. 오래되었던 공간으로 움직이게되었고, 오래되었던 공간의 물건 크기가 증가했다.

5

는 "할당 실패는"매우 극적으로 들리지만, 참여 진짜 실패는 없다. 단지 메모리를 너무 많이 할당했기 때문에 메모리를 수집 할 수 있는지 GC를 확인할 때가되었습니다.

--gc-global 플래그 ("GC forced by flags")로 실행중인 것 같습니다. 디버깅 할 때 문제를 좁히는 것이 좋을지라도 생산에는 나쁜 생각입니다.

귀하의 프로세스가 누출되는 이유를 알 수 없습니다. 힙 프로파일 러가 유용 할 수 있습니다. 코드에 따르면 https://github.com/felixge/node-memory-leak-tutorial

+0

예, 나는 힙 diff를 취하기 전에 모든 garbages를 수집하기 위해 --gc-global 및 compact를 사용하고 있습니다. 그건 사소한거야. 질문은 gc에서 mem가 증가하는 이유입니다. – haijin