หน่วยความจำรั่วเกิดขึ้นในโครงการ Python Google App Engine มีวิธีใดที่มีประสิทธิภาพในการเขียนการดำเนินการของฉันหรือไม่?

ฉันมีโครงการ GAE ที่เขียนด้วย Python ฉันสร้าง cron เพื่อดำเนินการแบบแบตช์ แต่ถึงขีดจำกัดหน่วยความจำส่วนตัวแบบซอฟต์ของอินสแตนซ์ F1 ซึ่งก็คือ 124MB หลังจากทำซ้ำไม่กี่ครั้ง ใครสามารถช่วยฉันเขียนโค้ดนี้ได้อย่างมีประสิทธิภาพมากขึ้น หวังว่าภายใน 124MB len(คน) ควรน้อยกว่า 500

def cron():
    q = Account.all().filter('role =', 1)
    people = [e for e in q]
    for p in people:
        s = Schedule.available(p)
        m = ScheduleMapper(s).as_dict()
        memcache.set('key_for_%s' % p.key(), m)

นี่คือเซิร์ฟเวอร์ dev และฉันไม่ต้องการอัปเกรดคลาสอินสแตนซ์ของฉัน นอกจากนี้ ฉันต้องการหลีกเลี่ยงการใช้ไลบรารีของบุคคลที่สาม เช่น numpy และ pandas

ฉันเพิ่มการรวบรวมขยะในบรรทัดสุดท้ายของ for loop แต่ดูเหมือนว่าจะไม่ทำงาน

del s
m.clear()
import gc
gc.collect()

comment
คุณไม่ได้กล่าวถึงจำนวนเอนทิตีที่คุณกำลังดึงข้อมูล นอกจากนี้ ฉันจะย้ายการวนซ้ำไปยังฟังก์ชันและ gc ภายนอก เมื่อคุณพูดว่าการวนซ้ำ คุณหมายถึงการเรียกใช้ตัวจัดการ cron หรือลูปด้านนอกหรือด้านในหรือไม่   -  person Tim Hoffman    schedule 02.10.2017
comment
ขอบคุณสำหรับความคิดเห็น! จำนวนเอนทิตีควรน้อยกว่า 500 สำหรับการวนซ้ำ ฉันหมายถึงวงใน   -  person steve    schedule 02.10.2017
comment
วงในมีกี่วงครับ. หากไม่เห็นโมเดลของคุณ ฉันสงสัยว่าคุณมีข้อมูลอ้างอิงอยู่ที่ไหนสักแห่ง   -  person Tim Hoffman    schedule 02.10.2017
comment
ฉันนับไม่แม่นเท่าไหร่ แต่จบลงแค่ไม่กี่อย่าง ใช่ ฉันก็สงสัยการอ้างอิงเหมือนกัน แต่จะปลดปล่อยความทรงจำทั้งหมดได้อย่างไร?   -  person steve    schedule 02.10.2017
comment
จากสิ่งที่ฉันเห็น del list หรือ dict.clear() จะไม่เปิดเผยความทรงจำทั้งหมด   -  person steve    schedule 02.10.2017
comment
ฉันคิดว่าเราจำเป็นต้องดูรายละเอียดบางอย่างใน available() และดูที่การซับสตรีมสิ่งที่คุณกำลังทำโดยไม่ต้องมีวัตถุระดับกลางทั้งหมด ดูที่การใช้แผนที่เพื่อใช้ฟังก์ชันกับเอนทิตีแทนที่จะแก้ไขรายการทั้งหมดแล้ววนซ้ำ สิ่งต่างๆเช่นนั้น ฉันมีกระบวนการที่มีการสืบค้นที่ทำงานได้หลายพันเอนทิตี และอินสแตนซ์ F1 ของฉันคงอยู่นานหลายวันและไม่เคยล้มเหลวโดยไม่มีข้อผิดพลาดจากหน่วยความจำไม่เพียงพอ   -  person Tim Hoffman    schedule 03.10.2017


คำตอบ (1)


หากต้องการดูว่าเป็นไปได้หรือไม่ที่จะปรับให้พอดีกับหน่วยความจำที่คุณต้องการแก้ไขแบบสอบถามของคุณเพื่อรับเอนทิตีเดียวและตรวจสอบว่าคุณสามารถดำเนินการ for วนซ้ำสำหรับเอนทิตีนั้นได้สำเร็จหรือไม่ หรือเพียงเพิ่ม break ที่ส่วนท้ายของ for ลูป :)

หากไม่ได้ผล คุณ ต้อง อัปเกรดคลาสอินสแตนซ์ของคุณ

หากการทดสอบใช้งานได้ คุณสามารถใช้การแบ่งงานโดยใช้ เคอร์เซอร์แบบสอบถาม ลงในงาน push Queue หลายงาน โดยแต่ละงาน ประมวลผลเพียงเอนทิตีเดียวหรือเพียงบางส่วนเท่านั้น

อาจดูที่ Google appengine: ประสิทธิภาพคิวงานสำหรับการสนทนา เรื่องการแบ่งงานออกเป็นหลายๆ งาน (ทั้งๆ ที่สาเหตุที่แยกงานในกรณีนั้นเกินกำหนดส่งคำขอ ไม่ใช่ขีดจำกัดหน่วยความจำ)

โปรดทราบว่าแม้จะใช้งานหลายอย่าง แต่ก็ยังเป็นไปได้ที่จะถึงขีดจำกัดของหน่วยความจำ (ดู App Engine Deferred: การติดตามหน่วยความจำรั่วไหล) แต่อย่างน้อยงานก็จะเสร็จสิ้นแม้ว่าจะมีการรีสตาร์ทอินสแตนซ์เฉพาะ (งานจะถูกลองใหม่ตามค่าเริ่มต้น)

person Dan Cornilescu    schedule 09.10.2017