delete 키워드는 객체를 반납하는 것이 아니라 객체를 참조하는 변수를 제거하는 것이라서 객체가 아닌 객체 참조를 제거하는 것에 불과하고.
따라서, 메모리 관리 면에서 보면 null 대입과 차이가 없고.
고로, ECMA스크립트 엔진을 제대로 구현하려면 쓰레기 수거가 반드시 들어가야 한다는 건데.
실제로 자바스크립트도 GC를 하고, 액션스크립트도 GC를 하는데,
액션스크립트가 메모리 관리 면에서는 좀 늦어서 플래쉬 7까지는 reference counting 기반의 쓰레기 수거를 해서 memory leak이 있었고, 플래쉬 8에서는 자바의 초기 GC 알고리즘은 mark and sweep 알고리즘을 사용해서 memory leak 문제를 개선했고.
Flash가 ECMAScript 언어 규격을 최대한 유지하려하지만 동일하지는 않습니다.(특히, ECMAScript의 버전이 올라갈 수록 차이점이 더 나고 있구요.) Flash의 delete 키워드가 C++처럼 명시적으로 객체를 반납하는 의미는 아닙니다만, 자바와 달리 모든 객체에 대해서 참조를 delete로 제거해야지만 메모리를 반납하는 점에서 자바의 gc와도 전혀 다르다고 볼수 있다고 생각이 되네요.
플래쉬나 자바스크립트나 언어에 있어서는 ECMAScript와 차이를 찾기가 어렵더군. 있다해도 사소한 부분에 불과하고, 액션스크립트와 자바스크립트의 차이는 본래 API와 API를 받쳐주는 런타임 환경의 차이에서 있었던 것이니깐.
물론, 액션스크립트 2.0에 오면서 자바스크립트에서는 아직 채용안한 ECMAScript 4판 드래프트를 채용해서 엄청나게 발전하기는 했던데.
이것때문에 플래쉬가 상당히 강력해진 것이고.
자바의 클래스 개념을 모두 가져가면서 dynamic typing나 prototoype 기반도 활용할 수 있어서 어떤 면에서는 자바보다 더 강력하다고 볼 수도 있고.
하지만, 메모리 관리에 관해서는 변한 게 없더군.
즉, 메모리 관리에 관한한 ECMAScript나 자바스크립트나 액션스크립트나 동일하다는 건데.
자바도 reference counnting 방식을 쓸 수도 있고 (실제로는 쓰지 않지만), 자바스크립트도 초기엔 reference counting을 썼다가 이젠 안 쓰고, 액션 스크립트도 마찬가지 현상이 좀 늦게 발생하는 것일 뿐인데.
그 이유는 자바는 초기부터 좀 큰 프로그램을 작성할 수 있는 다목적 프로그래밍 언어였기 때문에 처음부터 reference counting을 안 쓴 것 뿐이고, 자바스크립트나 액션스크립트는 큰 프로그램을 짜는 목적이 아니라서 메모리 leak 문제가 심각하지 않거나 수작업으로 쉽게 피해나가기 때문에 reference counting으로 해결한 것 같더군.
문제의 원인은 ECMAScript가 객체를 명시적으로 생성할 수 있지만 객체를 명시적으로 반납할 수 있는 기능을 제공하지 않으며 포인터 연산을 제공하지 않기때문에, delete와 같은 키워드 존재 여부와 상관없이 reference counting이든 mark and sweep이든 GC가 필요한 것이있고, 어떤 방식을 적용해도 기본적으로 동작하는 하는 것이고.
제가 좀 잘못안부분이 있었네요. gc는 있습니다. 다만, gc 전에 레퍼런스를 제거하기 위해서 delete를 사용합니다. 레퍼런스를 수동으로 일일히 제거하지 않으면 메모리를 제거하지 않습니다. 그리고, 제가 보는 책에는 null을 대입하여서 레퍼런스를 제거하는 부분에 대해서는 달리 언급이 없네요. 책을 보면 ECMAScript와 Actionscript2.0의 미묘한 차이점에 대해서 나와있습니다. 오버로딩이나 private의 개념의 차이점에 등에 대해서 나와있구요. 제가 여기서 예기하고 싶었던 것은 레퍼런스 자체를 모두 delete하지 않으면 안되기 때문에 기존의 자바 코드를 단순하게 Actionscript로 포팅해서 사용하기 어렵다는 예기를 하고 싶었던 것 뿐입니다.
기존의 자바 코드를 ActionScript로 포팅하는 데 메모리 관리 부분을 포함해서 별 문제가 안 될 것 같은데.
ActionScript가 자바 언어보다 더 많은 기능을 포함하기 때문에 언어면에 있어서는 포팅이 크게 어려울 것 같지 않고.
물론, 자바의 volatile, synchronized와 같은 스레드 관련 기능이나 네이티브 메소드 지원 기능이 보이지 않아서 문제가 될 수는 있지만.
하지만, 포팅에서 정말 곤란한 부분은 API의 차이에서 발생할 것 같군.
그리고, 플래쉬의 API를 제대로 활용하지 못한다면 포팅해도 나아지는 게 없을 것 같은 느낌이고 (더 열악해질 가능성도 다분하고).
한가지 있다면 플래쉬 런타임이 많이 퍼져 있다는 것을 활용할 수 있다는 것 정도...
액션스크립트의 delete 키워드에 대해서 명확하게 정의되어 있지 않는 것 같더군.
객체 참조를 제거하는 것인데 객체를 제거한다고 잘못 설명된 경우가 많아서 혼란을 가중시키는 경향도 있고.
액션스크립트(좀더 일반적으로는 ECMASCript)의 delete 키워드는 변수나 프로퍼티를 명시적으로 제거하고, 변수가 객체 참조를 저장한 경우에는 객체 참조도 제거되는 효과를 가져와서 객체 메모리 회수에 관해서는 null 대입과 동일한 효과를 갖는데, 추가적으로 변수가 차지하는 메모리는 명시적으로 반납되어 메모리가 좀더 많이 회수된다고 정리되는데.
즉, delete는 reference manual의 내용과는 달리 기술적으로는 객체 반납과 아무런 직접적인 관련이 없다는 것임.
그러나, delete가 꼭 필요한 이유는 자바와 같이 static typing에서는 변수의 갯수와 필드가 고정되어 있으나, ECMAScript에서는 변수와 필드를 무한히 늘릴 수 있으므로 객체도 아닌 것들 때문에 메모리 문제가 생길 수 있어서 명시적으로 제거할 필요가 있었던 것이고.
운좋게도, 변수나 필드는 객체가 아니라서 그 참조값이 다른 곳에 저장될 수 없어서 아무때나 제거해도 dangling pointer 문제가 발생하지 않는 것이고.
다시, 원래 문제로 돌아가서,
변수와 프로퍼티가 차지하는 메모리를 제거하는 것이 이슈가 되지 않는 경우에는 (자바를 액션스크립트로 포팅하는 경우등), delete나 null 대입이나 같은 효과를 갖고, 액션스크립트의 전역 변수는 자바의 클래스 변수에 대응하며, 제대로 쓰레기 수집되려면 자바에서도 클래스 변수에 적절히 null 대입해주어야 하는 것과 마찬가지로 액션스크립트도 변수에 null 대입해주는 것이라고 봐야하는데.
원문제의 결론은 메모리 관리를 이것 저것 다 필요없이 메모리 관리를 위해서 delete를 해줘야 한다는 예기구요. 포팅을 전제로 할 때 primitive type이 없다는 점(3.0에 일부있습니다.)이나, 숫자포멧은 Number 포멧하나만 지원한다는 점이나, private의 의미가 자신과 자신의 상속을 지원한다는 점이나 메소드 전달시 아규먼트의 개수가 적어도 자동적으로 처리된다거나 오버라이딩이 지원되지 않는 등의 점도 문제가 될 수 있습니다.
자바든 C#이든 자동으로 관리되는 건 메모리일뿐이고 (물론, 이 경우도 적절한 곳에 수작업으로 null 대입을 해준다는 가정하에서), 리소스 관리는 별도의 문제입니다.
물론, 제대로 만들어진 API에서는 메모리가 반납될 때 그 객체가 점유한 시스템 리소스도 자동으로 반납하지만, 경험하신 문제점과 같이 메모리가 반납될 때 리소스를 반납하기에는 너무 늦을 수 있으므로, 시스템 리소스를 점유하는 객체는 그 객체가 더이상 필요하지 않으면 곧바로 그 시스템 리소스를 명시적으로 반납하는 Dipose, Close 등의 메소드를 명시적으로 호출해주어야 합니다.
그러한 API를 제공하지 않으면 API의 결함이고, 그 API를 호출하지 않아서 발생한 문제는 어플리케이션의 결함입니다.
그럼 메모리 관리 해줘야 하나요? ㅡ,.ㅡ
답글삭제네 delete 해줘야 합니다.
답글삭제아.. 저 짤방으로 보아... 너무나 -_-;; 원통하고 분하셨나 보네요 ;;;;;
답글삭제당연한 예기를~
답글삭제직접 delete해 주는게 더 좋지 않나요? 전 GC가 미워요.
답글삭제직접 delete해주는게 좋기는 하지만.. delete한지도 꽤 오래되어서 기억이나 날런지 모르겠네요. ^^
답글삭제옷장수가 조금 오해하고 있는 것 같군.
답글삭제자바스크립트나 액션스크립트는 모두 ECMAScript를 언어 규격으로 신봉하고, API 면에 있어서는 각자 생각이 달라서 갈라진 것이라고 볼 수 있는데.
ECMAScript 언어에서는 명시적으로 객체를 생성하지만 C++처럼 명시적으로 객체를 반납할 수는 없지.
delete 키워드는 객체를 반납하는 것이 아니라 객체를 참조하는 변수를 제거하는 것이라서 객체가 아닌 객체 참조를 제거하는 것에 불과하고.
따라서, 메모리 관리 면에서 보면 null 대입과 차이가 없고.
고로, ECMA스크립트 엔진을 제대로 구현하려면 쓰레기 수거가 반드시 들어가야 한다는 건데.
실제로 자바스크립트도 GC를 하고, 액션스크립트도 GC를 하는데,
액션스크립트가 메모리 관리 면에서는 좀 늦어서 플래쉬 7까지는 reference counting 기반의 쓰레기 수거를 해서 memory leak이 있었고, 플래쉬 8에서는 자바의 초기 GC 알고리즘은 mark and sweep 알고리즘을 사용해서 memory leak 문제를 개선했고.
처음에 자바에 손대는 게 망설여졌던 이유는 무조건 GC를 하기 때문이었는데. ㅎㅎㅎ
답글삭제지금은 무조건 GC를 하는 언어도 마음에 안들고, 무조건 GC를 안하는 언어도 마음에 안들고.
GC가 필요한 코드를 만들지 그렇지 않을 지는 플랫폼이 결정해서는 안되고 프로그래머가 결정해야 한다는 생각이쥐.
Flash가 ECMAScript 언어 규격을 최대한 유지하려하지만 동일하지는 않습니다.(특히, ECMAScript의 버전이 올라갈 수록 차이점이 더 나고 있구요.) Flash의 delete 키워드가 C++처럼 명시적으로 객체를 반납하는 의미는 아닙니다만, 자바와 달리 모든 객체에 대해서 참조를 delete로 제거해야지만 메모리를 반납하는 점에서 자바의 gc와도 전혀 다르다고 볼수 있다고 생각이 되네요.
답글삭제플래쉬나 자바스크립트나 언어에 있어서는 ECMAScript와 차이를 찾기가 어렵더군. 있다해도 사소한 부분에 불과하고, 액션스크립트와 자바스크립트의 차이는 본래 API와 API를 받쳐주는 런타임 환경의 차이에서 있었던 것이니깐.
답글삭제물론, 액션스크립트 2.0에 오면서 자바스크립트에서는 아직 채용안한 ECMAScript 4판 드래프트를 채용해서 엄청나게 발전하기는 했던데.
이것때문에 플래쉬가 상당히 강력해진 것이고.
자바의 클래스 개념을 모두 가져가면서 dynamic typing나 prototoype 기반도 활용할 수 있어서 어떤 면에서는 자바보다 더 강력하다고 볼 수도 있고.
하지만, 메모리 관리에 관해서는 변한 게 없더군.
즉, 메모리 관리에 관한한 ECMAScript나 자바스크립트나 액션스크립트나 동일하다는 건데.
자바도 reference counnting 방식을 쓸 수도 있고 (실제로는 쓰지 않지만), 자바스크립트도 초기엔 reference counting을 썼다가 이젠 안 쓰고, 액션 스크립트도 마찬가지 현상이 좀 늦게 발생하는 것일 뿐인데.
그 이유는 자바는 초기부터 좀 큰 프로그램을 작성할 수 있는 다목적 프로그래밍 언어였기 때문에 처음부터 reference counting을 안 쓴 것 뿐이고, 자바스크립트나 액션스크립트는 큰 프로그램을 짜는 목적이 아니라서 메모리 leak 문제가 심각하지 않거나 수작업으로 쉽게 피해나가기 때문에 reference counting으로 해결한 것 같더군.
문제의 원인은 ECMAScript가 객체를 명시적으로 생성할 수 있지만 객체를 명시적으로 반납할 수 있는 기능을 제공하지 않으며 포인터 연산을 제공하지 않기때문에, delete와 같은 키워드 존재 여부와 상관없이 reference counting이든 mark and sweep이든 GC가 필요한 것이있고, 어떤 방식을 적용해도 기본적으로 동작하는 하는 것이고.
답글삭제delete 키워드는 변수나 프로퍼티를 명시적으로 메모리에서 제거할 수는 있지만, 메모리 관리에서 생각하는 건 변수가 아닌 객체를 반납하는 문제가 주요 이슈이니깐.
답글삭제객체에 관해서는 명시적인 제거가 아니라 참조만 제거하는 것이라고 말한 것인데.
가령, 액션스크립트가 매우 이상하게 만들어진 게 아니라면, 모든 변수를 delete하는 것이 아니라 null 대입만 해도 객체들이 모두 회수될텐데.
아니란 말인가?
비슷하게, 변수가 어떤 객체를 가리키고 있는데 그 변수를 delete해도 다른 변수가 그 객체를 가리키고 있으면 여전히 delete가 안될테고.
제가 좀 잘못안부분이 있었네요. gc는 있습니다. 다만, gc 전에 레퍼런스를 제거하기 위해서 delete를 사용합니다. 레퍼런스를 수동으로 일일히 제거하지 않으면 메모리를 제거하지 않습니다. 그리고, 제가 보는 책에는 null을 대입하여서 레퍼런스를 제거하는 부분에 대해서는 달리 언급이 없네요. 책을 보면 ECMAScript와 Actionscript2.0의 미묘한 차이점에 대해서 나와있습니다. 오버로딩이나 private의 개념의 차이점에 등에 대해서 나와있구요. 제가 여기서 예기하고 싶었던 것은 레퍼런스 자체를 모두 delete하지 않으면 안되기 때문에 기존의 자바 코드를 단순하게 Actionscript로 포팅해서 사용하기 어렵다는 예기를 하고 싶었던 것 뿐입니다.
답글삭제기존의 자바 코드를 ActionScript로 포팅하는 데 메모리 관리 부분을 포함해서 별 문제가 안 될 것 같은데.
답글삭제ActionScript가 자바 언어보다 더 많은 기능을 포함하기 때문에 언어면에 있어서는 포팅이 크게 어려울 것 같지 않고.
물론, 자바의 volatile, synchronized와 같은 스레드 관련 기능이나 네이티브 메소드 지원 기능이 보이지 않아서 문제가 될 수는 있지만.
하지만, 포팅에서 정말 곤란한 부분은 API의 차이에서 발생할 것 같군.
그리고, 플래쉬의 API를 제대로 활용하지 못한다면 포팅해도 나아지는 게 없을 것 같은 느낌이고 (더 열악해질 가능성도 다분하고).
한가지 있다면 플래쉬 런타임이 많이 퍼져 있다는 것을 활용할 수 있다는 것 정도...
액션스크립트의 delete 키워드에 대해서 명확하게 정의되어 있지 않는 것 같더군.
객체 참조를 제거하는 것인데 객체를 제거한다고 잘못 설명된 경우가 많아서 혼란을 가중시키는 경향도 있고.
액션스크립트(좀더 일반적으로는 ECMASCript)의 delete 키워드는 변수나 프로퍼티를 명시적으로 제거하고, 변수가 객체 참조를 저장한 경우에는 객체 참조도 제거되는 효과를 가져와서 객체 메모리 회수에 관해서는 null 대입과 동일한 효과를 갖는데, 추가적으로 변수가 차지하는 메모리는 명시적으로 반납되어 메모리가 좀더 많이 회수된다고 정리되는데.
즉, delete는 reference manual의 내용과는 달리 기술적으로는 객체 반납과 아무런 직접적인 관련이 없다는 것임.
그러나, delete가 꼭 필요한 이유는 자바와 같이 static typing에서는 변수의 갯수와 필드가 고정되어 있으나, ECMAScript에서는 변수와 필드를 무한히 늘릴 수 있으므로 객체도 아닌 것들 때문에 메모리 문제가 생길 수 있어서 명시적으로 제거할 필요가 있었던 것이고.
운좋게도, 변수나 필드는 객체가 아니라서 그 참조값이 다른 곳에 저장될 수 없어서 아무때나 제거해도 dangling pointer 문제가 발생하지 않는 것이고.
다시, 원래 문제로 돌아가서,
변수와 프로퍼티가 차지하는 메모리를 제거하는 것이 이슈가 되지 않는 경우에는 (자바를 액션스크립트로 포팅하는 경우등), delete나 null 대입이나 같은 효과를 갖고, 액션스크립트의 전역 변수는 자바의 클래스 변수에 대응하며, 제대로 쓰레기 수집되려면 자바에서도 클래스 변수에 적절히 null 대입해주어야 하는 것과 마찬가지로 액션스크립트도 변수에 null 대입해주는 것이라고 봐야하는데.
실험용으로 약간 큰 자바 프로그램을 플래쉬로 포팅해서 비교해보는 것도 괜찮을 것 같군.
답글삭제생각보다 플래쉬가 뛰어난 것 같더군.
플래쉬 = 자바(클래스, static typing, 바이트코드 효율성) + 자바스크립트(dynamic typing, prototype, DOM) + 멀티미디어 문서 형식 + 훌륭한 저작 도구
원문제의 결론은 메모리 관리를 이것 저것 다 필요없이 메모리 관리를 위해서 delete를 해줘야 한다는 예기구요. 포팅을 전제로 할 때 primitive type이 없다는 점(3.0에 일부있습니다.)이나, 숫자포멧은 Number 포멧하나만 지원한다는 점이나, private의 의미가 자신과 자신의 상속을 지원한다는 점이나 메소드 전달시 아규먼트의 개수가 적어도 자동적으로 처리된다거나 오버라이딩이 지원되지 않는 등의 점도 문제가 될 수 있습니다.
답글삭제리플을 다실가면 간단하게 달아주시고 길게 하실거면 트랙백을 사용하십시오. 길게 달경우 삭제하겠습니다.
답글삭제결론을 간단하게 얘기하면, 메모리 괸리의 관점에서 자바에서 수작업으로 null 대입하거나 액션스크립트에서 delete하는 것이나 본질상 비슷한 작업이라는 것을 의미한 것이었는데.
답글삭제즉, 액션스크립트에서 delete가 자바에 비해 특별히 메모리 관리면에서 프로그래밍하는 것이 불편한 것은 아니라는 거쥐.
명시적으로 다 지워버렸으면 좋겠다. 아 C#에서 리소스 해제를 안해주니까 이상한데서 익셉션 생겨서 한동안 골치아팠었다.
답글삭제지우게 해달라 지우게 해달라~~~
그냥 놔두면 리소스 관리 더 잘할지도 몰라~
답글삭제델버님, 무언가 오해가 있는 것 같군요.
답글삭제자바든 C#이든 자동으로 관리되는 건 메모리일뿐이고 (물론, 이 경우도 적절한 곳에 수작업으로 null 대입을 해준다는 가정하에서), 리소스 관리는 별도의 문제입니다.
물론, 제대로 만들어진 API에서는 메모리가 반납될 때 그 객체가 점유한 시스템 리소스도 자동으로 반납하지만, 경험하신 문제점과 같이 메모리가 반납될 때 리소스를 반납하기에는 너무 늦을 수 있으므로, 시스템 리소스를 점유하는 객체는 그 객체가 더이상 필요하지 않으면 곧바로 그 시스템 리소스를 명시적으로 반납하는 Dipose, Close 등의 메소드를 명시적으로 호출해주어야 합니다.
그러한 API를 제공하지 않으면 API의 결함이고, 그 API를 호출하지 않아서 발생한 문제는 어플리케이션의 결함입니다.
즐건하루님//중간에 댓글 안읽고 정수가 쓴 글만 보고 단 댓글입니다. 오해할만한 건 아마 없었을 겁니다. 그냥 농담삼아 던진 말이니까요^^
답글삭제