리소스 사용의 균형 [실용주의 프로그래머]

LEE KYU WON·2021년 1월 19일
0

최근 웹 개발에 주로 사용하는 언어들은 garbage collecting 이 지원되는 언어들이기 때문에 메모리 자원 관리를 자동으로 해주는 편이지만 그렇지 않은 경우를 위한 리소스 할당과 해제에 관한 내용이다.

실용주의 프로그래머 Tip 35
시작한것은 끝내라

이것은 단순히 리소스를 할당하는 루틴이나 객체가 리소스를 해제하는 책임 역시 져야한다는것 의미한다.

나쁜 코드는 리소스의 할당 부분과 리소스를 해제하는 부분이 분리되어있어 고아상태의 자원을 만들기 쉽게 한다. 따라서 한가지 루틴에서 할당한 자원은 반드시 그 루틴에서 할당을 해제해야 한다.

중첩할당

한번에 하나 이상의 리소스를 필요로 하는 루틴에서는 두가지 원칙을 더 지켜야 한다.

1. 리소스를 할당한 순서의 반대로 해제하라.
이렇게 해야 리소스가 다른 리소스를 참조하는 경우에도 리소스를 고아로 만들지 않는다. (LIFO)

2. 코드 여러곳에서 동일한 리소스 집합을 할당하는 경우 할당 순서를 같게 한다.
deadlock 의 가능성을 줄여준다.

객체와 예외

예외처리를 지원하는 언어의 경우 루틴의 분기가 여러개이고 해당 분기마다 자원 해제 코드를 넣는것은 DRY 원칙에 위배된다.

1. finally 를 지원하지 않는경우

C++ 같이 finally 를 지원하지 않는 경우는 해당 언어의 성질을 이용해서 DRY 원칙을 지키며 리소스 해제를 할 수 있다. C++ 의 지역 객체들은 자기를 둘러싼 블록에서 나갈 때 자동으로 파괴된다. 루틴에 사용되는 자원을 항상 로컬 객체에 위치시기면 된다. 만약 포인터를 사용 할 수 밖에 없는 상황에서는 wrapper 클래스로 해당 자원을 감쌀 수 있다.

2. finally 를 지원하는 경우

finally 문에서 자원을 해제 할 수 있다.

위의 원칙을 사용 할 수 없는 경우

예를 들어 동적인 자료 구조형을 사용하는 프로그램에서는 할당 한 메모리를 더 큰 구조체에 할당하기도 하고 이런것이 중첩되기도 한다. 그런 경우 세가지 방법중 하나를 선택 할 수 있다.

  1. 최상위 구조 자신이 자기 안에 들어있는 하위 구조들의 할당을 해제 할 책임이 있다.
  2. 최상위 구조에서 그냥 할당이 해제된다. (하위 구조들이 고아 자원이 됨.)
  3. 최상위 구조는 하나라도 하위구조를 가지고 있을경우 자기의 할당 해제를 거부한다.

어떤것을 선택 할지 명백히 하고 "계약에 의한 프로그래밍" 에 의해 일관성 있게 구현 할 수 있다.

이러한 방법이 까다로워진다면 할당된 객체에 참조 숫자세기 (reference counting) 을 구현해 자신만의 garbage collecting 을 구현 할 수 있다.

profile
벼랑끝에서 성장하는 개발자 이규원입니다.

0개의 댓글