# NativeContainer 구조체 복사

> Copy and reference multiple native containers.

[네이티브 컨테이너](/engine/6000.0/manual/scripting/optimization/job-system/native-container.md)는 값 유형이므로 변수에 할당되면 Unity는 네이티브 컨테이너의 데이터가 저장되는 위치([`AtomicSafetyHandle`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle.md) 포함)에 대한 포인터를 포함하는 `NativeContainer` 구조를 복사합니다. `NativeContainer`의 전체 내용을 복사하지는 않습니다.

이 시나리오는 모두 동일한 메모리 영역을 참조하고 모두 동일한 중앙 레코드를 참조하는 `AtomicSafetyHandle` 오브젝트를 포함한 `NativeContainer` 구조의 사본이 여러 개 있을 수 있음을 의미합니다.


**NativeContainer 오브젝트 사본의 작동 방식:**
![](/api/media?file=/engine/6000.0/media/images/native-container-diagram.png)

위의 다이어그램은 모두 동일한 실제 컨테이너를 나타내는 `NativeArray` 구조의 세 가지 사본을 보여 줍니다. 각 사본은 저장된 동일한 데이터 및 원본 `NativeArray`와 동일한 안전 데이터를 가리킵니다. 그러나 각 `NativeArray`의 사본에는 해당 사본으로 수행할 수 있는 잡을 나타내는 다른 플래그가 있습니다. 안전 데이터에 대한 포인터와 플래그가 결합되어 `AtomicSafetyHandle`을 구성합니다.

## 버전 번호

`NativeContainer`가 폐기되는 경우, 모든 `NativeContainer` 구조의 사본은 원본 `NativeContainer`가 무효임을 인식해야 합니다. 원본 `NativeContainer`의 폐기란 `NativeContainer`의 데이터를 저장하는 데 사용된 메모리 블록이 할당 해제되었음을 의미합니다. 이 경우 각 `NativeContainer` 사본에 저장된 데이터에 대한 포인터가 유효하지 않으며 사용 시 액세스 위반이 발생할 수 있습니다.

또한 `AtomicSafetyHandle`은 `NativeContainer` 인스턴스에 대해 무효화되는 중앙 기록을 가리킵니다. 하지만 안전 시스템은 중앙 레코드에 대한 메모리를 할당 해제하지 않으므로 액세스 위반의 위험을 방지합니다.

대신 각 기록에는 버전 번호가 포함됩니다. 해당 기록을 참조하는 각 `AtomicSafetyHandle` 내에 버전 번호 사본이 저장됩니다. NativeContainer가 폐기되면 Unity는 `Release()`를 호출하여 중앙 기록의 버전 번호를 증가시킵니다. 그런 다음 다른 `NativeContainer` 인스턴스에 대해 기록을 재사용할 수 있습니다.

나머지 `AtomicSafetyHandle `은 각각 저장된 버전 번호와 중앙 기록의 버전 번호를 비교하여 `NativeContainer`가 폐기되었는지 테스트합니다. Unity는 [`CheckReadAndThrow`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/check-read-and-throw.md) 및 [`CheckWriteAndThrow`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/check-write-and-throw.md)와 같은 메서드 호출의 일환으로 이 테스트를 자동으로 수행합니다.

## 동적 네이티브 컨테이너의 정적 뷰

동적 네이티브 컨테이너는 [`NativeList<T>`](https://docs.unity3d.com/Packages/com.unity.collections@latest/index.html?subfolder=/api/Unity.Collections.NativeList-1.html)(Collections 패키지에서 사용 가능)와 같이 요소를 계속 추가할 수 있는 변수 크기가 있는 컨테이너입니다. 이는 고정된 크기이며 변경할 수 없는 [`NativeArray<T>`](/engine/6000.0/script-reference/unity-collections/native-array-1.md)와 같은 정적 네이티브 컨테이너와 다릅니다.

동적 네이티브 컨테이너를 사용하는 경우 뷰라는 다른 인터페이스를 통해 해당 데이터에 직접 액세스할 수도 있습니다. 뷰를 사용하면 데이터를 복사하거나 소유권을 취하지 않고도 `NativeContainer` 오브젝트의 데이터에 별칭을 지정할 수 있습니다. 뷰의 예로는 네이티브 컨테이너의 데이터에 요소별로 액세스하는 데 사용할 수 있는 열거자 오브젝트와 `NativeList`를 `NativeArray`처럼 취급하는 데 사용할 수 있는 [`NativeList<T>.AsArray`](https://docs.unity3d.com/Packages/com.unity.collections@latest/index.html?subfolder=/api/Unity.Collections.NativeList-1.html#Unity_Collections_NativeList_1_AsArray)와 같은 메서드가 있습니다.

뷰는 일반적으로 동적 네이티브 컨테이너의 크기가 변경되는 경우 스레드에 안전하지 않습니다. 네이티브 컨테이너의 크기가 변경되면 Unity는 데이터가 메모리에 저장되는 위치를 재배치하므로 뷰에서 저장하는 모든 포인터가 무효화되기 때문입니다.

### 보조 버전 번호

동적 네이티브 컨테이너의 크기가 변경되는 상황을 지원하기 위해 안전 시스템은 `AtomicSafetyHandle`에 보조 버전 번호를 포함합니다. 이 메커니즘은 버전 지정 메커니즘과 유사하지만, 중앙 기록에 저장된 두 번째 버전 번호를 사용하며 이는 첫 번째 버전 번호와 독립적으로 증분할 수 있습니다.

보조 버전 번호를 사용하려면 [`UseSecondaryVersion`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/use-secondary-version.md)을 사용하여 `NativeContainer`에 저장된 데이터의 뷰를 설정할 수 있습니다. 네이티브 컨테이너의 크기를 변경하거나 기존 뷰를 무효화하는 작업의 경우 `CheckWriteAndThrow` 대신 [`CheckWriteAndBumpSecondaryVersion`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/check-write-and-bump-secondary-version.md)을 사용합니다. 또한 네이티브 컨테이너에 쓰는 잡이 예약될 때마다 뷰가 자동으로 무효화되도록 `NativeContainer`의 [`SetBumpSecondaryVersionOnScheduleWrite`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/set-bump-secondary-version-on-schedule-write.md)도 설정해야 합니다.

뷰를 생성하고 `AtomicSafetyHandle`을 뷰에 복사할 때 [`CheckGetSecondaryDataPointerAndThrow`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/check-get-secondary-data-pointer-and-throw.md)를 사용하여 네이티브 컨테이너의 메모리에 대한 포인터를 뷰에 복사할 수 있는지 확인합니다.

## 특수 핸들

임시 네이티브 컨테이너로 작업할 때 사용할 수 있는 두 가지 특수 핸들이 있습니다.

* [`GetTempMemoryHandle`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/get-temp-memory-handle.md): `Allocator.Temp`로 할당된 네이티브 컨테이너에서 사용할 수 있는 `AtomicSafetyHandle`을 반환합니다. 현재 임시 메모리 범위가 종료되면 Unity는 이 핸들을 자동으로 무효화하므로 직접 해제할 필요가 없습니다. 특정 `AtomicSafetyHandle`이 `GetTempMemoryHandle`에서 반환한 핸들인지 테스트하려면 `IsTempMemoryHandle`을 사용합니다.
* [`GetTempUnsafePtrSliceHandle`](/engine/6000.0/script-reference/unity-collections-low-level-unsafe/atomic-safety-handle/get-temp-unsafe-ptr-slice-handle.md): 안전하지 않은 메모리에서 지원되는 임시 네이티브 컨테이너에 사용 가능한 전역 핸들을 반환합니다. 예를 들면 스택 메모리로 구성된 `NativeSlice`가 있습니다. 이 핸들을 사용하는 컨테이너는 잡에 전달할 수 없습니다.

## 추가 리소스

* [커스텀 NativeContainer 구현](/engine/6000.0/manual/scripting/optimization/job-system/native-container/custom-nativecontainer.md)
* [커스텀 NativeContainer 예제](/engine/6000.0/manual/scripting/optimization/job-system/native-container/custom-nativecontainer-example.md)
