나는 최근에 [Flex / AIR / ActionScript3] Event 청취자와 메모리 관리 에 대한 글을 썼다.
그러나 놀랍게도 "불꽃남자"님께서 다음과 같이 지적해주셨다.
Flex의 메모리 문제에 대한 마지막 방법이
weakly reference로 모든 객체를 다루는것이지만...
무수한 테스트에 의해도....
결국 메모리는 털어지지 않습니다.
일반적인 OOP에서 메모리를 sweep하는 프로세스는
스레드가 담당을 하게 되고...그 스레드만의 stop the world를
통해 다른 실행중인 스레드가 영향을 받지 않게 해야지만,
AS3의 GC에는 그러한 구조가 없습니다.
weakly reference가 잘 동작하지 않는다고 Adobe측에 아주 강력하게
항의를 했지만, 돌아오는 답은 원래 그런거다...라는...
어이가 없죠?ㅋㅋㅋ
Flex Product Manager에게도 강력히 요청했으나.
Flex 3에서도 변한건 없습니다.
Large Application에서 GC를 정확히 할려면,
편법으로 밖에 할 수 없겠죠...참고로..Flex SDK안의 많은 오브젝트에 addEventListner가 구현되어있지만,
removeEventListner가 없는 코드가 더 많다는..ㅡ,ㅡ;;
이부분 역시 어도비에 따졌지만,
돌아오는 답은...원래 그런거다..그냥 써라..
역시 어이가 없죠?ㅋㅋㅋ
자기들이 가이드라인해준 방식을 SDK안에서 조차 적용이 안되어있는걸
어떻게 설명해야하나요?ㅡ,ㅡ;;아..그리고 위의 코드에서
용호님이 테스트 하셔서 좋은 정보 올려주세요.
objects.destroy();
objects = null;
을 호출하게 되면, 이론상으로 잘 돌아가야는데...
원래 OOP의 CG구조가 저렇게 destroy()를 시키고, null을 대입하면
바로 GC가 일어나는건 아닙니다.
하지만 최 우선순위를 두고 메모리에서 없애야 하는데,
Flash Player에서 그 타이밍이 언제인지는 아무도 모릅니다.
다만,
어도비에서 주장하는 바는 웹브라우저가 가용할 수 있는메모리, 혹은
Flash Player가 가용할 수 있는 메모리의 임계치까지 다 찼을때만
GC가 발생한다고 합니다.
이게 말이나 되는 일입니까?ㅎㅎ
그럼 destroy() 메소드는 왜 만들었으며, 객체에 null을 대입하는
코드는 무슨 소용이겠습니까?
좋은글 올려주셨는데, 우리가 생각하는데로 Flex가 동작하지 않기에
몇마디 달아봤습니다.ㅎㅎㅎ
수고하세요 지돌스타님~~~^^
그리고 위에서 보여주신 정보는 상당히 좋은 정보입니다.
보통 자바개발자라면 저러한 부분을 생각하지만,
그렇지 않은 분들도 많거든요.
외국에서도 weakly reference하게 개발하자고 많은 분들이 주장하시고 있고,
말씀하신 remove관련된 내용은 분명히 어플리케이션의 부하를 줄여주는
좋은 방법입니다.
메모리 문제 때문에 악받은 Flex 챔피언들 몇명있죠..ㅋㅋ
동호대표, 진욱대표...그리고 저..ㅋㅋㅋ
어도비 수석 엔지니어의 말로는 Flash Player 10이 나오면
해결 가능할것 같다...같다...라고 했습니다..ㅎㅎ
결국 무슨말이고하니....
이런식으로는 가비지 컬렉터(GC)가 바로 동작하지 않는다는 것이다.
그래서 실제로 그러한가 테스트 해보았다.
그랬더니... 정말 그러한 것이 아닌가?
수백개의 자식 컴포넌트를 추가한뒤 참조까지 삭제후 부모에서 떼어냈는데도... System.totalMemory 값은 거의 불변이었다. 재미있는 것은 다시 수백개의 자식을 추가하는 동안 갑자기 System.totalMemory가 증가만 하는것이 아니라 뚝 떨어지는 시기가 있다. 즉, 프로그래머는 메모리 관리는 내 마음대로 할 수 없다는 것을 의미한다. Flash Player가 알아서 어느정도 GC 대상이 만들어졌을 경우 삭제한다는 것이다.
한가지 중요한 점은 [Flex / AIR / ActionScript3] Event 청취자와 메모리 관리 글에서 쓴 것처럼 최소작업은 해야 그나마 Flash Player의 GC가 동작할 수 있다는 것이다. 그래서 쓸데없는 글은 아니였구나 생각했다.
더 재미있는 것이 있다.
바로 System.gc() 함수이다.
이 함수는 GC를 강제적으로 실행해준다. 그...그런데....
gc () method public static function gc():void
Forces the garbage collection process.
For the Flash Player debugger version and AIR applications only. In an AIR application, the
gc()
method is only enabled in content running in the AIR Debug Launcher (ADL) or, in an installed applcation, in content in the application security sandbox.Player Version: Flash Player 9 Update 3 or the AIR Debug Launcher (ADL).
Flash Player debugger와 AIR Applications 에서만 동작한단다....
즉, 배포용 Flash/Flex 프로그램에서는 동작하지 않는다는 말이다.
왜 이렇게 만들었지???? ㅡㅡ;;;;;
테스트 소스를 받아봐서 실행해보길 바란다(Flex 3기반)
이 소스는 http://wooyaggo.tistory.com/search/system.gc 에서 제공한 소스를 참고했다.
만약 Flex나 Flash 프로그래머라면 Flash Player가 debug버전으로 설치되어 있을 것이다. 그 상태에서는 System.gc()가 잘 동작하므로 GC가 매우 잘 동작하는 것처럼 보일것이다. 하지만
http://wooyaggo.tistory.com/112
에서 Flash Player Uninstaller를 이용해 debug용 Flash Player를 삭제한 후 보통 Flash Player 를 설치후 방금 받은 소스를 실행해보자.
그럼 System.gc()는 제대로 동작안되고 GC가 동작되는 시기가 Flash Player에서 임의로 정해진다.
결론적으로 이러한 환경에서는
되도록이면 객체를 최소한 만들고
모듈화를 최대한 활용하며
재활용할 수 있는 것은 재활용하면서 사용하는 것이
메모리관리에 도움된다.
아~~~ 다 좋은데.... 왜 메모리가 이렇게 골치아프게 만드는 것이냐.... ㅡㅡ;;
잘못된 내용이나 추가할 사항이 있다면 언제든지 지적해주세요.
이러한 사항은 함께 공유해야 한다고 생각하거든요.
읽을거리 : AIR/Flex: Memory optimisation
글쓴이 : 지돌스타(http://blog.jidolstar.com/319)