2014-12-20 2 views
1

저는 Tkinter를 사용하여 파이썬에서 아주 간단한 게임을 작업 해 왔습니다. 모든 게임 객체를 포함하는 List가 있으며, List가 순환되고 List의 각 객체가 자체적으로 윈도우에 그려지는 메인 루프의 모든 진드기가 있습니다.메모리에서 참조가없는 파이썬 객체 지우기

사용자가 레이저를 발사 할 때마다 새 레이저 개체가 변수에 할당되지 않고 목록에 동적으로 추가됩니다. 단순화 된 형태로, 이렇게하는 거예요

if buttonIsPressed: 
    game.itemlist.append(LaserObject()) 

레이저가이 창에 위치를 테스트하고 특정 지점에 도달 할 때, 그것은 목록에서 자신을 제거하고 더 이상 그려 그 자체를 그릴 때. 아무런 언급이 없지만, 어쨌든 기억에 남아있는 것 같습니다.

레이저를 발사하고 더 많은 레이저 개체를 생성하는 동안 프로그램의 메모리 사용량이 위아래로 증가합니다. 테스트로서, 메모리 사용량이 10MB가 될 때까지했습니다. 그런 다음 프로그램을 참조없이 한 번만 레이저 개체가 가비지 수집되고 프로그램의 메모리 사용량이 갈 수 있는지 확인하기 위해 한 시간 동안 그대로 두었습니다. 뒤로 물러나지 만 절대로하지 않았다. 그것은 10 MB에서 바로 머물렀다.

이러한 상황에서 레이저 객체를 가비지 수집하여 메모리를 계속 차지하지 않도록해야하며 프로그램의 전체 메모리 사용량이 일정하게 유지 될 수 있습니까?

+0

내 tkinter 지식은 약간 녹슬었지만 레이저 개체를 만드는 코드를보아야한다고 생각합니다. –

+0

'gc.collect()'를 호출하고'gc.garbage'의 내용을 확인하십시오. LaserObject가 어떤 이유로 든 해제 할 수없는 내부 개체를 만들고있을 수 있습니다. 가비지 목록에 LaserObject가 있으면'__del__' 메서드를 정의하거나 하나의 클래스를 서브 클래 싱하는 것입니까? – Dunes

+0

개체가 삭제되고 사용되지 않는 개체가 가비지 수집 된 경우에도 파이썬 인터프리터가 메모리를 다시 운영 체제로 돌려 준다고 생각하지 않습니다. 즉, 프로세스의 메모리 사용 공간이 결코 작아지지 않습니다. – martineau

답변

0

레이블이 메모리에서 제거되지 않는 문제가 있습니다.

원래 각 LaserObject에는 레이저 이미지가 그려진 레이블이 있습니다. 나중에 캔버스에서 직접 이미지를 그리기로 전환했지만 Label 객체는 LaserObject 내부에 남아있어 제대로 삭제되지 않았습니다.

Label을 LaserObject에서 완전히 제거했을 때 이미지가 캔버스에 미친 것처럼 깜박 거리기 시작했습니다. 아마도 이미지에 대한 참조를 유지하는 Label과 관련이있어서 가비지 수집을 너무 일찍하거나 그렇게하지 못하게 할 수 있습니다. .

이 상황을 해결하는 가장 좋은 방법은 Label을 LaserObject에 유지하면서 LaserObject가 항목 목록에서 제거되면 Label을 삭제하는 코드를 추가하는 것입니다. 이렇게하면 :

if laser.y == past_edge_of_window: 
    self.game.itemlist.remove(laser) 
    self.label.destroy() 

이렇게하면 Tk가 해당 Label 객체의 모든 내부 코드를 정리하고 메모리 사용을 일정하게 유지합니다.

관련 문제