2012-08-12 5 views
1

항상 스마트 포인터 동작에 대한 새로운 정의를 다시 작성할 가능성에 대해 읽었지 만 지금은 실제 예제를 찾을 수 없습니다. 할 수있는 새로운 상태를 추가로스마트 포인터의 동작과 라이프 사이클을 재정의/재정의하는 방법은 무엇입니까?

이 이

스마트 포인터 참조 횟수 또는 수명주기를 관리하는 링크 참조를 사용하고, 내 기본 문제가 구성 :

지금 나는 해결책을 얻을 수 있다면이 문제를 제안하고보고 싶어 릴리스 및 내 포인터의 삭제가 발생하면 이벤트가 트리거 될 때 리소스를 비우는 것이 좋습니다.

게임을 할 때 일반적으로 모든 리소스가로드되고 해제되며 사용자가 레벨 1에서 레벨 2로 넘어갈 때 해제되므로 레벨 1의 리소스가 해제됩니다. 또한 자동 참조 카운팅을 기다릴 수 없어서 레벨 2에서 레벨 1의 리소스를 사용하지 않으면 자동으로 해제 될 것이라고 생각하므로이 예제를 계속 사용하고 싶습니다. 더 이상 요청되지 않았기 때문에 자동으로 해제됩니다. ; 이것은 사실 일 수 있지만 사용자가 스트레스를 받고 컴퓨터를 사용할 때 메모리로 작동하는 것은 정말 나쁜 행동입니다.

나는 스마트 포인터를 사용하고 싶습니다. 왜냐하면 저는 그들이 제공하는 다른 모든 기능에도 관심이 있기 때문입니다.하지만 그들은 저에게 큰 단점을 가지고 있으며 직접적인 라이프 사이클을 직접 관리해야합니다.

어떤 옵션이 있습니까?

+0

"레벨"개체가있는 경우 수준을 변경할 때 올바른 개체를 유지하는 것이 쉽습니다. – mfontanini

+0

@mfontanini 네,하지만 문제는 다른 사람들을 풀어내는 방법입니다. 그리고 레벨의 변화가 있고 자동문을 기다리지 않을 때 이것을하는 방법이 있습니다. – user827992

+0

옵저버 패턴은 어떻습니까? http://en.wikipedia.org/wiki/Observer_pattern – ForEveR

답변

4

방금 ​​공유 포인터를 던져 버렸고 리소스 소유권에 대해 적절하게 생각하는 것처럼 들리는 것 같습니다. 설명에서 그것은 레벨 개체가 이러한 모든 리소스를 소유해야한다는 것을 분명히합니다. 즉, 과 공유되지 않아야하므로 참조 계산이 전혀 필요하지 않습니다.

스마트 포인터를 사용하면 적절한 시간에 수동으로 자원을 해제해야하는 부담을 덜 수 있지만 적절한 시간을 생각하지 않아도됩니다.

내가 정확하고 수준이 리소스를 소유해야한다면 고유 한 소유권을 제공하는 스마트 포인터를 사용하거나 자동 개체를 사용하고 스마트 포인터를 신경 쓰지 마세요. 이러한 객체에 대한 액세스가 필요한 레벨을 제외한 다른 모든 객체는 소유하지 않은 포인터 또는 참조, 즉 전통적인 포인터 또는 참조가 필요합니다.

내가 틀렸고 리소스를 실제로 공유해야하는 경우 레벨을 삭제할 때 리소스가 해제되어서는 안됩니다. 소유권을 공유하는 다른 객체는 리소스를 좋아하지 않습니다.

3

레벨이 끝난 후에도 공유 포인터가 남아 있다면 레벨 공유 기간 동안 호출 된 함수 스택에 공유 포인터가 자동 변수로 할당되지 않았기 때문입니다. 오히려 일부 유형의 컨테이너 또는 전체적으로 액세스 할 수있는 일련의 컨테이너에 저장됩니다. 따라서 중요한 문제는 각 레벨에 대한 리소스를 관리하는 공유 포인터를 포함하는 컨테이너의 라이프 사이클을 관리하는 것입니다.

예를 들어, 일부 함수 foo 내의 스택에 할당 된 스마트 포인터는 함수 호출 기간에 해당하는 수명 만 갖습니다. 함수 호출이 완료되면 공유 포인터가 파기됩니다. 리소스를 여전히 가리키는 추가 공유 포인터가있는 경우 리소스 자체는 삭제되지 않지만 추가 공유 포인터는 호출 수신자 스택이 아닌 다른 위치에 있어야합니다. 그래서 당신의 임무는 "다른 위치"를 관리하는 것입니다.이 컨테이너는 전 세계적으로 액세스 할 수있는 일련의 컨테이너 일 가능성이 높습니다.

따라서 각 레벨에 대한 데이터를 관리하는 컨테이너를 플러시하면 각 레벨에 할당 된 자원을 완전히 파괴해야합니다. 원하는 경우 컨테이너의 플러시를 트리거하는 데 이벤트 기반 인터페이스 또는 간단한 관찰자 패턴을 사용하거나 레벨 리소스의 수명을 관리하는 객체에 대해 소멸자가 명시 적으로 명시 적으로 수행 할 수 있습니다.

결국 리소스 관리가 내려집니다 ... 공유 포인터가 메모리 누수를 방지하기 위해 설계 되었기 때문에 할당 된 방법이나 위치를 추적해서는 안됩니다. 공유 포인터의 저장소를 중앙 집중화하면 관리하는 리소스를 파괴하는 것이 그리 큰 문제가되지 않습니다.

2

정말 공유 포인터를 사용해서는 안되는 것 같습니다. 커스텀 deallocator를 지정하여 동작을 재정의하는 방법이 있지만 다른 유형의 "스마트 포인터"를 고려할 것입니다.

Apache 웹 서버는 메모리 풀을 사용하여 요청과 관련된 모든 자원의 할당을 해제합니다. 요청은 메모리 풀을 소유합니다. 서버 내부에 메모리를 할당 할 때 할당 할 풀을 식별해야합니다. 서버는 수명이 다른 소수의 메모리 풀을 유지합니다. 하나는 서버 인스턴스 용이고 다른 하나는 모듈 용이고 다른 하나는 각 요청 용입니다. 이것은 상황에 더 잘 맞는 것처럼 들립니다.

Apache 코드는 메모리 관리를 위해 Apache Portable Runtime을 사용합니다. 그것은 C로 작성되었으며 현재하고있는 일과 가장 잘 어울리지 않을 수 있습니다. Boost에는 메모리 풀 라이브러리도 있지만 사용하지는 않았습니다.

3

앞서 언급했듯이 특정 문제에 대한 공유 포인터가 올바른 해결책이 아닐 수도 있습니다. 그러나 예를 들어 레벨 해제를 시간 분할하려는 경우 수동으로 해당 파괴를 수동으로 관리 할 수 ​​있습니다 (또는 메모리 압력이 너무 높지 않거나 관심이없는 경우 여분의 CPU 사이클이있을 때까지 기다릴 수도 있습니다).). 자원을 다 끝내면 전역 대기열 (또는 여러 대기열, 유형 또는 우선 순위 등에 따라 하나씩)에서 쉽게 삭제 대기열에 올려 놓습니다. 나중에 큐를 처리하고 참조를 제거하십시오. 참으로 마지막 참조 일 경우 개체의 파기를 유발합니다. 예를 들어 몇 번의 반복을 할 때마다 타이머를 쉽게 확인하고 1ms를 자유롭게 사용하고 다음 프레임에서 종료하고 계속 진행하는지 확인하십시오.

레벨 당 메모리 풀 (또는 자산 패키지 당)을 사용하면 성능이 현저히 향상됩니다. 메모리 관리가 쉬워지며 때때로 전체 풀을 한 번에 해제하고 안에있는 모든 객체의 소멸자를 호출하지 않아도됩니다 (아무 것도하지 않는다는 것을 알고 있다면!).

관련 문제