2014-01-07 7 views
1

약 800k 문서를 처리하는 데몬을 작성했는데 메모리 부족 문제가 있습니다.치명적인 오류가 발생했습니다.

mongodb에서 문서를 가져올 때마다 루프마다 메모리 사용량이 증가합니다.

func main() { 
session, err := mgo.Dial("localhost") 
if err != nil { panic(err) } 
defer session.Close() 

subscriptionsC = session.DB("sm").C("subscriptions") 
subscriptions := []Subscription{} 

for { 
    subscriptions = GetSubscriptions() 

그리고 다른 기능은 다음과 같습니다

func GetSubscriptions()([]Subscription) { 
    result := []Subscription{} 
    err := subscriptionsC.Find(nil).Prefetch(0.0).All(&result) 

    if err != nil { Log("signups_err", err.Error() + "\n") } 
    return result 
} 

는 각 루프 또는 정확히 어떤 일을 가진 배열을 재 선언 않다면 모르겠어요.

도움을 주시면 감사하겠습니다.

+0

'for' 루프는 무한 루프이며 매 반복마다 Mongo의 결과를 수집합니다. – elithrar

+0

세션이 결과를 캐싱 할 가능성이 있습니까? 테스트를 위해 루프를 통해 실행될 때마다 subscriptionsC 객체를 닫거나 다시 만들 수 있습니다. –

답변

0

배열은 GetSubscriptions()을 호출하고 루프 result := []Subscription{}을 호출하기 때문에 모든 루프에서 반드시 초기화됩니다.하지만 문제의 원인이 아닌 것 같습니다.

문제가 글로벌 세션에서 발생했을 수 있습니다. Database connections in web applications을 참조하십시오. 적절한 방법은 세션 풀을 사용하는 것입니다.

편집는 : 여기 산화 마그네슘의 How do I call mongoDB CRUD method from handler?

+0

오류는 http://pastebin.com/n9b0teSR입니다. 여기서 139는 GetSubscriptions()의 "err"이고 166은 subscriptions = GetSubscriptions()입니다. – eastercow

+0

정확히'err'은'subscriptionsC'에 의한 것이므로 전역 세션 대신 다른 패턴을 사용해야하는 것 같습니다. 참조 : https://groups.google.com/d/msg/mgo-users/d62BH1iuzFc/J1cgd5gWjnUJ – ymg

+0

고마워요. 그것을하기 전에 나는 쿼리에서 $로 테스트했다.반환되는 레코드 수가 적 으면 메모리 사용량이 안정적이며 가비지 수집이 제대로 작동 한 것으로 보입니다. – eastercow

1

저자를 참조하십시오.

코드에 문제가 없지만 불완전하므로 실제로 보이지 않는 것이 실제로 메모리 누수 일 가능성이 있습니다.

메모리 누수에 대한 전체 예제를 제공 할 수 있습니까?

mgo가 내부적으로 리소스 풀링을 처리하기 때문에 캐싱/풀링 세션에는 아무런 의미가 없습니다. 수행해야하는 작업은 작성한 세션을 닫는 것입니다 (샘플 코드는 해당 세션을 닫아야합니다). 아래 OP의 코멘트 후

업데이트 :

문제가 문서의 높은 양 것 같다. pastebin.com/jUDmbS4z 매 10-15 분마다 한 번씩 충돌합니다 (약 4-5 루프). mongo에서 한 번에 약 600,000 개의 문서를 가져옵니다.

그래, 쉽게 산화 마그네슘 관련이없는 이유 .. 메모리 조각화, 비 정밀 수집 등의 숫자에 대한 문제를 만들 수 있습니다 한 번에 메모리에있는 데이터의 말도 안되는 금액을로드하는 쿼리를 실행 그냥 항목을 반복 그들이 평소와 같이 도착할 때; 그것은 당신이 이미 생각한 것처럼 편안하고 빠르며, 사용 된 메모리의 양을 대폭 줄일 것입니다.

+0

것은 컬렉션에서 모든 것을 얻지 못하고 데몬이 완벽하게 작동하고 있습니다. 7 월 1 일 이후로 더 이상 메모리가 누출되지 않고 다시 시작되지 않습니다. 문제는 많은 양의 문서가있는 것으로 보입니다. http://pastebin.com/jUDmbS4z 10-15 분마다 한 번씩 충돌합니다 (약 4-5 루프). mongo에서 한 번에 약 600,000 개의 문서를 가져옵니다. 배열을 채우는 대신 forEach()를 사용하면 문제가 해결 될 것이지만 쿼리의 수가 증가한다고 생각합니다. – eastercow

+0

하아 .. 알았어. 너는 그때 기억의 톤을 사용한다. 그것은 mgo의 누수가 아닙니다. 응답을 업데이트했습니다. –

+0

절대로, 나는 골란 버그에 대해 더 많이 생각하고 있었지만 그들은 최신 릴리스로 수정했다고 말하진 않았습니다. – eastercow

관련 문제