सबसे पहले, DEBUG = False
सेटिंग्स.py में, इसलिए नहीं, connections['default'].queries
तब तक बढ़ रहा है जब तक यह सभी मेमोरी का उपयोग नहीं करता है।डीजेंगो में बड़े प्रश्नों (या प्रश्नों की श्रृंखला) के बाद सिस्टम को स्मृति क्यों जारी नहीं किया जाता है?
इस तथ्य से शुरुआत करें कि मैंने User
तालिका django.contrib.auth.models.User
से 10000 उपयोगकर्ताओं के साथ लोड की है (प्रत्येक नाम 'परीक्षण #' जहां # 1 और 10000 के बीच एक संख्या है)।
यहाँ दृश्य है:
from django.contrib.auth.models import User
from django.http import HttpResponse
import time
def leak(request):
print "loading users"
users = []
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
users += list(User.objects.all())
print "sleeping"
time.sleep(10)
return HttpResponse('')
मैं /leak/
यूआरएल के लिए ऊपर दृश्य जुड़ा हुआ है और (डीबग = झूठी साथ विकास सर्वर प्रारंभ है, और मैं परीक्षण किया है और यह कुछ भी नहीं गया है अन्य उदाहरण बनाम विकास सर्वर चलाने के साथ करें)।
चलाने के बाद:
% curl http://localhost:8000/leak/
runserver प्रक्रिया 'स्मृति आकार के नीचे ps aux
उत्पादन से देखा चारों ओर करने के लिए बढ़ता है और फिर उस स्तर पर रहता है।
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
dlamotte 25694 11.5 34.8 861384 705668 pts/3 Sl+ 19:11 2:52 /home/dlamotte/tmp/django-mem-leak/env/bin/python ./manage.py runserver
फिर ऊपर curl
आदेश ऊपर चल रहा है विकसित करने के लिए उदाहरण के स्मृति उपयोग (जो मैं एक सच्चे स्मृति रिसाव से उम्मीद?), इसे फिर से उपयोग करना चाहिए स्मृति प्रतीत नहीं होता? हालांकि, मुझे लगता है कि यहां कुछ गड़बड़ है कि स्मृति को सिस्टम में रिलीज़ नहीं किया जाता है (हालांकि, मैं समझता हूं कि यह बेहतर प्रदर्शन हो सकता है कि पायथन स्मृति को जारी नहीं करता है)।
इसके बाद, मैंने यह देखने का प्रयास किया कि क्या पाइथन आवंटित स्मृति के बड़े हिस्से को जारी करेगा या नहीं। तो मैं एक अजगर सत्र से निम्नलिखित का प्रयास:
>>> a = ''
>>> a += 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' * 10000000
>>> del a
स्मृति a += ...
लाइन के रूप में उम्मीद पर आवंटित किया जाता है, लेकिन जब del a
होता है, स्मृति जारी किया गया है। Django क्वेरी सेट के लिए व्यवहार अलग क्यों है? क्या ऐसा कुछ है जो डीजेंगो करना चाहता है? क्या इस व्यवहार को बदलने का कोई तरीका है?
मैंने सचमुच इस व्यवहार को डिबग करने में 2 दिन बिताए हैं, इस बारे में कोई विचार नहीं है कि मुझे आगे जाना है (मैंने गप्पी और ओबजग्राफ का उपयोग करना सीखा है जो कि मुझे पता चल सकता है कि कुछ भी दिलचस्प नहीं है)।
अद्यतन: इस काम में बस अजगर स्मृति प्रबंधन हो सकता है और Django के साथ कुछ नहीं (Django उपयोगकर्ताओं की मेलिंग सूची पर सुझाव) हो सकता था, लेकिन मैं किसी भी तरह Django के बाहर अजगर में इस नकल की पुष्टि करना चाहते हैं।
अद्यतन: अजगर संस्करण आवेदनों की 2.6.5
+1। इस सवाल के जवाब में बहुत दिलचस्पी है। मैंने डीजेगो के साथ उत्पादन पर कुछ समय के साथ अजीब स्मृति रिसाव भी पहचाना (DEBUG = झूठा भी और यहां तक कि बहुत ही सरल ऐप्स/परियोजनाओं के साथ)। –
यदि आप 'डेल उपयोगकर्ता' हैं तो क्या होता है? –
पाइथन का कौन सा संस्करण आप उपयोग कर रहे हैं (सर्वर और कमांड लाइन परीक्षण दोनों के लिए)? पुराने संस्करण सिस्टम पर ऑब्जेक्ट्स के लिए आवंटित स्मृति को रिलीज़ नहीं करते हैं, इसलिए यदि आपका स्थानीय संस्करण 2.5 या बाद वाला है, लेकिन आपका सर्वर 2.4 चल रहा है, तो यह आपकी समस्या हो सकती है। एकल बड़े आवंटन (आपकी बड़ी स्ट्रिंग की तरह) आवंटक को भी बाईपास कर सकता है - देखें कि '([[]] * 10 ** 6) जैसे कुछ के साथ क्या होता है। – ncoghlan