2014-07-11 1 views
0

나는 데이터베이스를 관리하기 위해 독립형으로 Django ORM을 사용하는 파이썬 응용 프로그램을 개발 중이지만 큰 메모리 문제에 직면하고 있습니다.장고 메모리 누수

ports_list_save = [] 
    for host in results['hosts']: 
     for protocol in results['hosts'][host]['protocols']: 
      for port in results['hosts'][host]['protocols'][protocol]: 
       current_port = history.Port(number=int(port), 
              protocol=protocol, 
              state=results['hosts'][host]['protocols'][protocol][port]['state'], 
              service='', 
              version='', 
              address=history.Ip.objects.get(scan=self.scan, address=host)) 
       ports_list_save.append(current_port) 
    history.Port.objects.bulk_create(ports_list_save) 

이 부분은 154 개 호스트와 호스트 당 150 개 포트 (23000) 저장하는 객체와 함께 잘 작동하지만, 지금은 1000 개 포트를 시도하고있다 :이 문제를 일으키는 부분 인 것으로 나타났습니다 내 컴퓨터의 메모리가 매번 폭발합니다.

한가지 더, 내가 디버그 모드에서 Django을 운영하지 않는, 그래서 당신은 많은 양의 데이터가있는 경우 메모리는 여전히 덩어리에 & 과정로드해야 할 수 있습니다 django.db.backends.postgresql_psycopg2.base.DatabaseWrapper

+0

나는 아니에요 확실히 그 문제를 이해합니다. 데이터 수를 10 배로 늘려서 메모리 사용량이 ~ 10 배 증가 할 것으로 예상해야합니다. 여기 뭔가 이상한 일이 있습니까? 나는. 왜 메모리 누수가 있다고 생각하니? – freakish

+0

이 프로세스는 2Go 이상의 RAM + 1Go 스왑을 사용하여 최대 10 자의 100k * 3 문자열을 처리하므로 너무 많이 들립니다. – Coriolis

+0

하지만 당신은 문자열을 다루지 않습니다. 이것들은 파이썬 객체입니다. 데이터의 모든 작은 부분은 메모리를 사용하며 킬로바이트를 사용할 수 있습니다. 메모리 누수처럼 보이지 않습니다. – freakish

답변

1

에서 오지 않는다 이 시도 :

CHUNK_SIZE = 23000 
ports_list_save = [] 
for host in results['hosts']: 
    for protocol in results['hosts'][host]['protocols']: 
     for port in results['hosts'][host]['protocols'][protocol]: 
      current_port = history.Port(number=int(port), 
             protocol=protocol, 
             state=results['hosts'][host]['protocols'][protocol][port]['state'], 
             service='', 
             version='', 
             address=history.Ip.objects.get(scan=self.scan, address=host)) 
      ports_list_save.append(current_port) 
      if len(ports_list_save) > CHUNK_SIZE: 
       history.Port.objects.bulk_create(ports_list_save) 
       ports_list_save = [] 
if ports_list_save: 
    history.Port.objects.bulk_create(ports_list_save) 
+0

작동 꽤 괜찮습니다, thx :). Btw, 나는 너무 효과가있는 것을 발견했다. "결과 [ '호스트']"루프의 호스트에 대해 "gc.collect()"가 끝날 때마다 호출한다. 나쁜 일입니까? 가장 좋은 방법은? – Coriolis

+0

잘 모르겠습니다. 'gc.collect() '를 호출하면 아무런 상처를 입지 않을 것이지만 많은 이점을 얻을 지 확신 할 수 없습니다. 나는 당신이 중요한 개선을 보지 않는 한 그것을 버리고 싶습니다. – monkut

0

내가 같은 문제에 직면하고이 솔루션 결국 :

class BulkCreateManager(object): 

    model = None 
    chunk_size = None 
    instances = None 

    def __init__(self, model, chunk_size=None, *args): 
     self.model = model 
     self.chunk_size = chunk_size 
     self.instances = [] 

    def append(self, instance): 
     if self.chunk_size and len(self.instances) > self.chunk_size: 
      self.create() 
      self.instances = [] 

     self.instances.append(instance) 

    def create(self): 
     self.model.objects.bulk_create(self.instances) 



ports_list_save = BulkCreateManager(history.Port, 23000) 
for host in results['hosts']: 
    for protocol in results['hosts'][host]['protocols']: 
     for port in results['hosts'][host]['protocols'][protocol]: 
      current_port = history.Port(number=int(port), 
             protocol=protocol, 
             state=results['hosts'][host]['protocols'][protocol][port]['state'], 
             service='', 
             version='', 
             address=history.Ip.objects.get(scan=self.scan, address=host)) 
      ports_list_save.append(current_port) 

ports_list_save.create()