CA2115: 네이티브 리소스를 사용하는 경우에는 GC.KeepAlive를 호출하십시오.
TypeName |
CallGCKeepAliveWhenUsingNativeResources |
CheckId |
CA2115 |
범주 |
Microsoft.Security |
변경 수준 |
주요 변경 아님 |
원인
종료자가 있는 형식에 선언된 메서드가 IntPtr 또는 UIntPtr 필드를 참조하지만 GC.KeepAlive를 호출하지 않습니다.
규칙 설명
관리 코드에서 더 이상 개체를 참조하지 않으면 가비지 수집에서 해당 개체를 종료합니다.개체에 대한 관리되지 않는 참조가 있어도 가비지 수집이 수행됩니다.이 규칙에서는 관리되지 않는 리소스가 비관리 코드에서 여전히 사용되고 있는데 종료되려고 할 경우 발생할 수 있는 오류를 감지합니다.
이 규칙에서는 IntPtr 및 UIntPtr 필드에 관리되지 않는 리소스에 대한 포인터가 저장된다고 가정합니다.종료자의 목적은 관리되지 않는 리소스를 해제하는 것이므로 이 규칙에서는 포인터 필드에서 가리키는 관리되지 않는 리소스를 종료자가 해제한다고 가정합니다.또한 관리되지 않는 리소스를 비관리 코드로 전달하는 포인터 필드를 메서드가 참조하고 있다고 가정합니다.
위반 문제를 해결하는 방법
이 규칙 위반 문제를 해결하려면 KeepAlive 호출을 메서드에 추가하고 현재 인스턴스(C# 및 C++에서는 this)를 인수로 전달합니다.가비지 수집으로부터 개체를 보호해야 하는 코드의 마지막 줄 이후에 호출을 배치합니다.KeepAlive 호출 이후부터는 개체에 대한 관리되는 참조가 없다고 간주되어 개체가 다시 가비지 수집이 가능한 상태가 됩니다.
경고를 표시하지 않는 경우
이 규칙에서 미리 가정하는 사항으로 인해 가양성(false positives)이 나타날 수 있습니다.다음과 같은 경우 이 규칙에서 경고를 표시하지 않아도 안전합니다.
이들을 제외하기 전에 다른 메시지를 충분히 검토하십시오.이 규칙에서 감지하는 오류는 재현하거나 디버깅하기 어렵습니다.
예제
다음 예제에서는 BadMethod 는 GC.KeepAlive 을 호출하는 것을 포함하고 있지 않고 규칙을 위반합니다.GoodMethod에는 올바른 코드가 들어 있습니다.
[!참고]
이 예제 코드는 의사 코드로 이 코드를 컴파일하고 실행하고 있지만 관리되지 않는 리소스가 생성 되거나 해제하지 않으므로 경고는 발생하지 않습니다.
using System;
namespace SecurityRulesLibrary
{
class IntPtrFieldsAndFinalizeRequireGCKeepAlive
{
private IntPtr unmanagedResource;
IntPtrFieldsAndFinalizeRequireGCKeepAlive()
{
GetUnmanagedResource (unmanagedResource);
}
// The finalizer frees the unmanaged resource.
~IntPtrFieldsAndFinalizeRequireGCKeepAlive()
{
FreeUnmanagedResource (unmanagedResource);
}
// Violates rule:CallGCKeepAliveWhenUsingNativeResources.
void BadMethod()
{
// Call some unmanaged code.
CallUnmanagedCode(unmanagedResource);
}
// Satisfies the rule.
void GoodMethod()
{
// Call some unmanaged code.
CallUnmanagedCode(unmanagedResource);
GC.KeepAlive(this);
}
// Methods that would typically make calls to unmanaged code.
void GetUnmanagedResource(IntPtr p)
{
// Allocate the resource ...
}
void FreeUnmanagedResource(IntPtr p)
{
// Free the resource and set the pointer to null ...
}
void CallUnmanagedCode(IntPtr p)
{
// Use the resource in unmanaged code ...
}
}
}
참고 항목
참조
기타 리소스
Implementing Finalize and Dispose to Clean Up Unmanaged Resources