2016-06-22 12 views
1

Ниже код имеет утечку памяти. Он работает под рубином 2.1.1. Я не могу найти фактическую утечку.Ошибка памяти в памяти рубинового кода в петле

q = Queue.new("test") 
while true do 
    m = q.dequeue 
    body = JSON.parse(m.body) 
    user_id = body["Records"][0] 
    user = V2::User.find(user_id) 
    post = V2::Post.find(post_id) 
end 

Через несколько часов бега я добавил GC.start, но ее не решает проблему

q = Queue.new("test") 
while true do 
    m = q.dequeue 
    body = JSON.parse(m.body) 
    user_id = body["Records"][0] 
    user = V2::User.find(user_id) 
    post = V2::Post.find(post_id) 
    GC.start 
end 

Я не знаю, как найти реальную утечку памяти.

+3

Как определяется «Очередь»? Что выглядит 'Queue # dequeue' (я заметил, что' dequeue' не определен для 'Queue', который поставляется с Ruby)? Кто помещает объекты в очередь? Сколько объектов в очереди в среднем? – spickermann

+0

На ваш вопрос ответили? – Dbz

ответ

1

Попробуйте удалить линии снизу вверх и посмотреть, не исчезла ли утечка памяти. Возможно, утечка памяти происходит из метода find или, возможно, JSON.parse (крайне маловероятно) или настраиваемой структуры данных очереди. Если утечка памяти по-прежнему сохраняется после удаления всех строк, это, скорее всего, происходит от самого рабочего и/или от программы, в которой работают рабочие.

q = Queue.new("test") 
while true do 
    m = q.dequeue # Finally remove this and stub the while true with a sleep or something 
    body = JSON.parse(m.body) # Then remove these two lines 
    user_id = body["Records"][0] 
    user = V2::User.find(user_id) # Remove the bottom two lines first 
    post = V2::Post.find(post_id) 
end 
+0

На первый взгляд я думал то же самое. Эта петля наверняка привела бы к высокому использованию ЦП, но почему это должно привести к высокому использованию памяти? – spickermann

+0

@Dbz На самом деле его рабочий. Он будет работать каждую секунду. Он будет листировать очередь. если какое-либо сообщение помещается в очередь, оно будет принимать сообщение из очереди и выполнять задание. – SaravanaKumAr

+0

Yup. Вы, ребята, определенно верны. Я обновил свой ответ с помощью советов по отладке. Обязательно опубликуйте результаты после попытки этого. – Dbz

0

Уверен, что проблема связана с введенными локальными переменными (sic!). Избавьтесь от user_id и post_id и, скорее всего, остановить утечку:

# user_id = body["Records"][0] 
# user = V2::User.find(user_id) 
user = V2::User.find(body["Records"][0]) # sic! 

Причина заключается в том, как Руби stores objects in RValues.

+0

После каждого GC.start локальные переменные памяти будут освобождены обрядом? – SaravanaKumAr

+0

Нет, не так. Пожалуйста, следуйте ответу, который я связал. – mudasobwa

+0

Например, я запускаю цикл 1000 раз. Внутри этого цикла каждый раз я просто назначаю user_id = some_value. Также каждый цикл запускает GC.start. В этом случае, когда память будет освобождена ?. Каково ваше мнение по этому поводу. while i <1000 i ++ user_id = i GC.start конец – SaravanaKumAr