django 메모리 이상 검사 및 해결 방법 기록
Django 는 Python 의 유명한 웹 프레임 워 크 로 서 많은 사람들 이 사용 하고 있 을 것 이 라 고 믿 습 니 다.자신의 작업 중 에 도 프로젝트 항목 이 사용 되 고 있 습 니 다.최근 며칠 동안 사용 한 결과 Django 프로그램 을 배치 한 서버 에 메모리 문제 가 발생 했 습 니 다.현상 은 한 동안 실행 한 후에 메모리 사용량 이 많 지 않 고 결국은 서버 의 메모리 가 소 진 되 고 Python 프로젝트 에 메모리 문제 가 발생 하 는 것 입 니 다.자신 이 이전에 한 번 처리 한 적 이 있 기 때문에 처음 해결 할 때 당황 하지 않 았 다.자신 이 전에 해결 방법 도 정리 했다.https://www.jb51.net/article/151604.htm
그러나 일 은 내 가 생각 하 는 것 처럼 그렇게 간단 하지 않 은 것 같다.스스로 이전의 방법 인 tracemalloc 라 이브 러 리 로 문 제 를 조사 하려 고 시도 했다.그러나 문 제 는 실제 프로젝트 에 100 여 개의 인터페이스 가 있 는데 어떻게 조사 합 니까?인터페이스 하나 로 테스트 검 사 를 하 는 것 은 아니 지만 시간 이 급 해서 또 늦 었 을 것 이다.지난번 에 스스로 해결 한 것 보다 지난번 프로젝트 가 간단 하고 상대 적 으로 포 지 셔 닝 문제 가 쉬 웠 기 때 문 입 니 다.그럼 이번 에는 어떻게 처리 하 시 겠 습 니까?
처리 과정
일반적으로 Python 프로젝트 는 메모리 문제 가 거의 발생 하지 않 습 니 다.보통 자신의 코드 에 문제 가 있어 서 발생 합 니 다.이번에 발생 한 문제 에 대해 자신의 조사 방향(웹 인터페이스 유형 에 대한 프로젝트):
사실 이런 인 터 페 이 스 는 초급 개발 에 문제 가 생기 기 쉬 운 부분 일 수 있다.먼저 이런 인터페이스 조회 의 데 이 터 는 다른 인터페이스 에 비해 비교적 복잡 할 것 이다.만약 에 인 코딩 기초 가 특별히 좋 지 않 으 면 이런 인터페이스 에 bug 가 나타 날 수 있다.
이번 조사 에서 최종 적 으로 데 이 터 를 모 은 인터페이스 에서 문제 가 Django ORM 의 부적 절 한 사용 으로 인 한 것 으로 확인 되 었 다.자신 은 간단 한 코드 인 스 턴 스 를 통 해 설명 합 니 다.
class Student(models.Model):
name = models.CharField(max_length=20)
name2 = models.CharField(max_length=20)
name3 = models.CharField(max_length=20)
name4 = models.CharField(max_length=20)
name5 = models.CharField(max_length=20)
name6 = models.CharField(max_length=20)
name7 = models.CharField(max_length=20)
name8 = models.CharField(max_length=20)
name9 = models.CharField(max_length=20)
name10 = models.CharField(max_length=20)
name11 = models.CharField(max_length=20)
name12 = models.CharField(max_length=20)
name13 = models.CharField(max_length=20)
name14 = models.CharField(max_length=20)
name15 = models.CharField(max_length=20)
age = models.IntegerField(default=0)
정상 적 인 상황 에서 우리 의 표 필드 는 비교적 많 을 것 이다.여 기 는 여러 개의 name 을 통 해 시 뮬 레이 션 을 하고 문제 가 발생 한 코드 는 이 표 에 관 한 인터페이스 에서 나온다.
def index(request):
studets = Student.objects.filter(age__gt=20)
if studets:
pass
return HttpResponse("test memory")
메모리 문 제 를 쉽게 재현 하기 위해 저 는 스 크 립 트 를 통 해 Student 에 20000 개의 데 이 터 를 삽 입 했 습 니 다.물론 여기 데이터 가 많 을 수록 문제 가 뚜렷 합 니 다.테스트 스 크 립 트 를 통 해 이 인 터 페 이 스 를 요청 하고 메모리 상황 을 관찰 하면 메모리 가 순식간에 올 라 가 는 상황 을 발견 할 수 있 습 니 다.또한 데이터 가 많 을 수록 요청 이 많 을 수록 메모리 가 한동안 높 아 지지 않 고 점점 올 라 갈 수 있 습 니 다.문제 가 어디 에 있 습 니까?
사실은 매우 간단 합 니 다.문 제 는 코드 에 있 는 if 판단 에 있 습 니 다.우 리 는 filter 조 회 를 통 해 Query Set 형식의 데 이 터 를 되 돌려 주 었 습 니 다.우리 가 걸 러 낸 데 이 터 는 매우 많은 경우 가 있 을 수 있 습 니 다.이때 우 리 는 if 를 통 해 직접 판단 합 니 다.이 지역 을 이해 해 야 전체 Query Set 을 메모리 에 불 러 와 메모리 사용량 이 너무 높 은 문제 가 발생 할 수 있 습 니 다.그리고 이때 이 인터페이스의 응답 속도 도 매우 느 려 집 니 다.이 Query Set 의 데이터 가 많 을 수록 메모리 사용량 이 뚜렷 합 니 다.
Django 문서 에서 사실 설명 을 했 어 요.
exists()¶
Returns True if the QuerySet contains any results, and False if not. This tries to perform the query in the simplest and fastest way possible, but it does execute nearly the same query as a normal QuerySet query.
exists() is useful for searches relating to both object membership in a QuerySet and to the existence of any objects in a QuerySet, particularly in the context of a large QuerySet.
The most efficient method of finding whether a model with a unique field (e.g. primary_key) is a member of a QuerySet is:
entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
print("Entry contained in queryset")
Which will be faster than the following which requires evaluating and iterating through the entire queryset:
if entry in some_queryset:
print("Entry contained in QuerySet")
And to find whether a queryset contains any items:
if some_queryset.exists():
print("There is at least one object in some_queryset")
Which will be faster than:
if some_queryset:
print("There is at least one object in some_queryset")
… but not by a large degree (hence needing a large queryset for efficiency gains).Additionally, if a some_queryset has not yet been evaluated, but you know that it will be at some point, then using some_queryset.exists() will do more overall work (one query for the existence check plus an extra one to later retrieve the results) than using bool(some_queryset), which retrieves the results and then checks if any were returned.
그래서 저희 코드 에 대해 서 는 if 판단 부분 을 if not studtets.exists()로 바 꾸 면 문 제 를 해결 할 수 있 습 니 다.
이것 은 아주 작은 지식 이지 만 잘못 사용 하면 매우 심각 한 메모리 문 제 를 일 으 킬 수 있다.
총결산
단원 테스트 를 제외 하고 빅 데이터 테스트 도 해 야 한다.이번 문 제 는 테스트 할 때 일정한 데이터 양 을 테스트 한 적 이 있다 면 일찍 발견 할 수 있 을 것 이다.
문제.
기초 라 이브 러 리 의 사용 에 대해 더욱 익숙해 져 야 한다.
문 제 를 조사 하 는 방향 은 명확 해 야 한다.그렇지 않 으 면 손 쓸 길이 없 을 것 이다.
연장 읽 기
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django의 질문 및 답변 웹사이트환영 친구, 이것은 우리의 새로운 블로그입니다. 이 블로그에서는 , 과 같은 Question-n-Answer 웹사이트를 만들고 있습니다. 이 웹사이트는 회원가입 및 로그인이 가능합니다. 로그인 후 사용자는 사용자의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.