나는 꽤 늙었다. 나는 거기에 있었고 그것을 보았고 그것에 대해 여러 번 머리를 부딪쳤다.
저는 허 슬리 파크 (Hursley Park)에서 열린 컨퍼런스에서 IBM 소년들이이 새로운 Java 언어가 얼마나 멋진 지 말해주었습니다. 누군가 만 물었습니다. 그는 우리가 C ++에서 소멸자로 알고있는 것을 의미하지는 않았지만 finaliser 도 없었습니다 (또는 finalisers가 있었지만 기본적으로 작동하지 않았습니다). 이것은 돌아 왔고, 우리는 Java가 그 시점에서 약간의 장난감 언어라고 결정했습니다.
이제 그들은 언어 사양에 Finalisers를 추가했으며 Java는 일부 채택을 보았습니다.
물론 나중에 모든 사람들은 GC를 엄청나게 늦추기 때문에 파이널 라이저를 객체에 넣지 말라고 들었습니다. (힙을 잠글뿐만 아니라 최종 대상이 될 객체를 임시 영역으로 이동해야했기 때문에 GC가 앱 실행을 일시 중지했기 때문에 이러한 메소드를 호출 할 수 없었습니다. 대신 다음 바로 전에 호출됩니다. GC 사이클) (그리고 더 나쁜 것은 앱이 종료 될 때 파이널 라이저가 전혀 호출되지 않는 경우가 있습니다. 파일 핸들을 닫지 않았다고 상상해보십시오)
그런 다음 우리는 C #을 가졌으며 MSDN에서이 새로운 C # 언어가 얼마나 멋진 지에 관한 토론 포럼을 기억합니다. 누군가 결정 론적 마무리가없는 이유를 물었고 MS 소년들은 우리에게 그러한 것들이 필요하지 않은 방법을 말한 다음 앱 디자인 방식을 변경해야한다고 말한 다음 GC가 얼마나 놀라운 지, 모든 오래된 앱이 어떻게되었는지 알려주었습니다. 모든 순환 참조 때문에 쓰레기와 결코 작동하지 않았습니다. 그런 다음 그들은 압력에 굴복하여 우리가 사용할 수있는 사양 에이 IDispose 패턴을 추가했다고 말했습니다. 그 시점에서 C # 앱에서 수동 메모리 관리로 되돌아 간 것으로 생각했습니다.
물론, MS 소년들은 나중에 그들이 우리에게 말한 모든 것이 ... 음, IDispose를 표준 인터페이스보다 조금 더 만들고 나중에 using 문을 추가했다는 것을 발견했습니다. W00t! 그들은 결정 론적 마무리가 결국 언어에서 빠졌다는 것을 깨달았습니다. 물론, 당신은 여전히 어딘가에 넣는 것을 기억해야하므로 여전히 약간 수동이지만 더 좋습니다.
그렇다면 처음부터 각 스코프 블록에 사용 스타일 의미론을 자동으로 배치 할 수 있었을 때 왜 그렇게 했습니까? 아마 효율성이지만, 나는 그들이 깨닫지 못했다고 생각합니다. 결국 그들은 여전히 .NET (Google SafeHandle)에 스마트 포인터가 필요하다는 것을 깨달았으므로 GC가 실제로 모든 문제를 해결할 것이라고 생각했습니다. 그들은 객체가 단순한 메모리 이상이고 GC가 주로 메모리 관리를 처리하도록 설계되었음을 잊었습니다. 그들은 GC가 이것을 처리 할 것이라는 생각에 사로 잡혔고, 당신이 거기에 다른 것들을 넣는 것을 잊어 버렸습니다. 오브젝트는 한동안 삭제하지 않으면 중요하지 않은 메모리 덩어리가 아닙니다.
그러나 원래 Java에 finalize 메소드가 없으면 조금 더 많은 것으로 생각합니다. 생성 한 객체는 메모리에 관한 것이고 DB 핸들이나 소켓 또는 기타와 같은 다른 것을 삭제하려는 경우 ) 그러면 수동으로해야 합니다.
Java는 사람들이 많은 수동 할당으로 C 코드를 작성하는 데 익숙한 임베디드 환경을 위해 설계되었으므로 자동 무료를 사용하지 않는 것은 큰 문제가 아니 었습니다. 이전에는 한 번도 해보지 않았으므로 Java에서 왜 필요할까요? 이 문제는 스레드 또는 스택 / 힙과 관련이 없으며 메모리 할당 (및 할당 해제)을 좀 더 쉽게하기 위해있을 수 있습니다. 대체로 try / finally 문은 비 메모리 리소스를 처리하기에 더 좋은 곳일 것입니다.
따라서 .NET이 Java의 가장 큰 결함을 단순히 복사 한 방식 인 IMHO는 가장 큰 약점입니다. .NET은 더 나은 Java가 아닌 더 나은 C ++이어야합니다.