모든 객체를로 설정해야합니까?null
(Nothing
VB.NET에서) 일단 당신이 그들과 함께 끝냈습니까?
NET에서 그것을 구현하는 개체의 인스턴스를 처리하는 것이 필수적입니다.IDisposable
객체가 처리 된 후에도 여전히 무언가가 될 수 있지만 일부 리소스를 해제하는 인터페이스isDisposed
양식의 속성), 그래서 그것은 여전히 메모리 또는 적어도 부분적으로 상주 할 수 있다고 가정합니까?
또한 객체가 범위를 벗어날 때 가비지 컬렉터의 다음 단계를 위해 컬렉션을 위해 표시된다는 것을 알고 있습니다 (시간이 걸릴 수도 있음).
따라서 이것을 염두에두고null
시스템이 더 이상 범위를 벗어나고 나쁜 부작용이 없다는 사실을 기억할 필요가 없으므로 시스템의 속도를 높일 수 있습니까?
MSDN 기사는 예제에서는이 작업을 수행하지 않으며 현재로서는이 작업을 수행 할 수 없습니다. 해를보십시오. 그러나 의견이 섞여서 어떤 의견이라도 유용합니다.
Karl은 절대적으로 정확합니다. 사용 후 객체를 null로 설정할 필요가 없습니다. 객체가 구현 된 경우IDisposable
, 당신이 전화했는지 확인하십시오.IDisposable.Dispose()
그 물건으로 끝내면 (try
..finally
, 또는 ausing()
블록). 하지만 전화를하지 않은 경우에도Dispose()
, 개체의 finalizer 메서드는 호출해야합니다.Dispose()
너를 위해서.
나는 이것이 좋은 치료라고 생각 :
이
자체 조정 및 불투명이기 때문에 GC 및 관리 전략을 추측 해 볼 필요가 없습니다. 제프리 리히터 (Dot Net Rocks)의 내부 작업에 대한 좋은 토론이있었습니다.Jeffrey Richter, Windows 메모리 모델과 판사의 서적C #을 통한 CLR20 장은 훌륭한 치료법입니다 :
작업을 마쳤을 때 객체를 null로 설정하지 않는 또 다른 이유는 실제로 객체를 오래 유지할 수 있다는 것입니다.
을 포함한다.
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is now eligible for garbage collection
// ... rest of method not using 'someType' ...
}
someType에 의해 참조 된 객체가 "DoSomething"을 호출 한 후 GC 될 수 있습니다.
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is NOT eligible for garbage collection yet
// because that variable is used at the end of the method
// ... rest of method not using 'someType' ...
someType = null;
}
메소드의 끝까지 객체를 유지할 수 있습니다. 그만큼JIT는 일반적으로 할당을 null로 최적화합니다.따라서 두 비트의 코드는 모두 동일하게됩니다.
GC.KeepAlive(someType);
만나다ericlippert.com/2013/06/10/construction-destruction - NotMe
객체를 null로 설정하지 마십시오. 체크 아웃 할 수 있습니다.http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx더 많은 정보를 원한다면, 당신의 코드를 더티 (dirty)하는 것을 제외하고는, 아무 것도하지 않는다.
또한:
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
일반적으로 사용 후 객체를 null로 할 필요는 없지만 경우에 따라 객체를 사용하는 것이 좋습니다.
개체가 IDisposable을 구현하고 필드에 저장되어있는 경우 폐기 된 개체를 사용하지 않으려면 null로 설정하는 것이 좋습니다. 다음 종류의 버그는 고통 스러울 수 있습니다.
this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();
필드를 삭제 한 후에 필드를 null로 설정하고 필드가 다시 사용되는 행에서 NullPtrEx 권한을 얻는 것이 좋습니다. 그렇지 않으면, DoSomething이하는 일에 따라 줄을 따라 일부 위험한 버그가 발생할 수 있습니다.
.Dispose()
. 찾으면 IDisposable을 올바르게 사용하지 않습니다. 일회용 물체의 유일한 용도는 사용 블록의 경계에 있어야합니다. 그리고 using-block을 사용하면myField
더 이상. 그리고 using 블록 내에서null
필요하지 않으면 using-block은 객체를 처리합니다. - Suamere
코드의 필요성을 느낀다면 코드가 충분히 구조화되지 않을 가능성이 있습니다.null
변수.
변수의 범위를 제한하는 데는 여러 가지 방법이 있습니다.
언급 한 바와 같이스티브 트란 비
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
비슷하게 중괄호를 사용할 수도 있습니다.
{
// Declare the variable and use it
SomeObject object = new SomeObject()
}
// The variable is no longer available
코드를 실제로 없애고 이해하기 쉽도록 "제목"없이 중괄호를 사용하는 것을 발견했습니다.
변수를 null로 설정해야하는 유일한 경우는 변수가 범위를 벗어나 더 이상 관련 데이터가 필요하지 않을 때입니다. 그렇지 않으면 필요가 없습니다.
일반적으로 null로 설정할 필요가 없습니다. 그러나 클래스에 리셋 기능이 있다고 가정 해보십시오.
Dispose를 올바르게 구현하지 못하고 System.ObjectDisposed 예외를 throw 할 수 있으므로 Dispose를 두 번 호출하지 않으려 고하기 때문에 수행 할 수 있습니다.
private void Reset()
{
if(_dataset != null)
{
_dataset.Dispose();
_dataset = null;
}
//..More such member variables like oracle connection etc. _oraConnection
}
이런 종류의 "사용 후에 객체를 null로 설정할 필요가 없습니다"는 완전히 정확하지는 않습니다. 변수를 삭제 한 후에 NULL을 사용해야하는 경우가 있습니다.
예, 항상 통화해야합니다..Dispose()
또는.Close()
당신이 끝났을 때 가지고있는 모든 것에. 파일 핸들, 데이터베이스 연결 또는 일회용 개체 일 수 있습니다.
그것과는 별도로 LazyLoad의 실용적인 패턴이 있습니다.
내가 인스턴스화했다고 가정 해 보겠습니다.ObjA
의class A
.Class A
공개 재산이있다.PropB
의class B
.
내부적으로,PropB
개인 변수를 사용합니다._B
기본값은 null입니다. 언제PropB.Get()
이 (가) 사용되면_PropB
null 인 경우는, 인스턴스를 생성하는데 필요한 자원을 엽니 다.B
으로_PropB
. 그런 다음 반환합니다._PropB
.
내 경험에 비추어 볼 때 이것은 정말 유용한 트릭입니다.
null 값의 필요성은 A를 재설정하거나 A의 내용을 어떤 식으로 변경하면_PropB
이전 값의 아이였다.A
, 당신은 폐기해야합니다 및 null을_PropB
따라서 LazyLoad는 코드에서 필요로하는 경우 올바른 값을 가져 오도록 재설정 할 수 있습니다.
너만하면_PropB.Dispose()
LazyLoad에 대한 null 검사가 성공할 것으로 예상되면 잠시 후 NULL이되지 않으며 부실 데이터가 표시됩니다. 사실상,Dispose()
확인차.
나는 그것이 틀림없이 있었으면 좋았을 텐데, 나는 지금이 행동을 보여주는 코드를 가지고있다.Dispose()
~에_PropB
그리고 Dispose를 수행 한 호출 함수 외부에서 (따라서 범위를 벗어나서) private prop는 여전히 null이 아니며 부실 데이터는 여전히 존재합니다.
결국 폐기 된 속성은 null이되지만 내 관점에서는 비 결정적입니다.
핵심 이유는 dbkk에서 알 수 있듯이 상위 컨테이너 (ObjA
와PropB
)의 인스턴스를 유지하고있다._PropB
범위에도 불구하고,Dispose()
.
참조를 null로하는 것이 의미있는 경우가 있습니다. 예를 들어, 우선 순위 대기열과 같은 콜렉션을 작성하고 계약서를 작성할 때, 클라이언트가 대기열에서 해당 오브젝트를 제거한 후에는 클라이언트에 대해 해당 오브젝트를 활성 상태로 유지하지 않아야합니다.
그러나 이런 종류의 것은 오랫동안 살아온 컬렉션에서만 중요합니다. 대기열이 생성 된 함수의 끝에서 생존하지 못한다면 전체적으로 훨씬 덜 중요합니다.
전반적으로, 당신은 정말로 신경 쓰지 않아야합니다. 컴파일러와 GC가 당신의 일을 할 수있게하십시오.
이 기사를 살펴보십시오.http://www.codeproject.com/KB/cs/idisposable.aspx
대부분의 경우, 오브젝트를 null로 설정해도 효과는 없습니다. 이렇게해야하는 유일한 시간은 크기가 84K (비트 맵)보다 큰 "대형 오브젝트"로 작업하는 경우입니다.
GC 구현 자의 설계에 의해 믿을 수 없다.속도를 올리다무효화 된 GC. GC를 실행하는 방법 / 방법에 대해 걱정하지 않으려 고합니다. 유비쿼터스처럼 취급하십시오.존재너를 보호하고 지켜 보며 ... (머리를 숙이고 하늘로 주먹을니다) ...
개인적으로, 나는 셀프 문서화의 형태로 변수를 다룰 때 변수를 null로 명시 적으로 설정합니다. 선언하고, 사용하고, 나중에 null로 설정하지 않습니다. 더 이상 필요하지 않으면 즉시 null입니다. 나는 분명히 말합니다, "나는 공식적으로 너와 끝났어 ... 가버 리다."
GC 된 언어에서 무효화가 필요합니까? 아닙니다. GC에 도움이됩니까? 어쩌면 예, 어쩌면 아니요, 확실하지 않습니다. 설계 상으로는 제어 할 수 없으며, 현재 버전의 응답 또는 미래의 GC 구현에 관계없이 미래의 GC 구현은 제 제어 범위를 벗어나는 응답을 변경할 수 있습니다. 또한 nulling이 최적화 된 경우 더 멋지다.논평당신이 원한다면.
내 발걸음을 따라가는 다음 가난한 바보에게 나의 의도가 더 명확하게 드러난다면"힘"잠재적으로 GC를 도움이되는 경우, 나에게 가치있는 것입니다. 대부분 그것이 나를 깔끔하고 깨끗하게 느끼게하고 몽고는 깔끔하고 깨끗하게 느끼기를 좋아합니다. :)
나는 이것을 다음과 같이 보았다 : 사람들이 다른 사람들에게 의도와 컴파일러에 대해 무엇을해야하는지에 대한 아이디어를주기 위해 프로그래밍 언어가 존재한다 - 컴파일러는 그 요청을 다른 언어 (때로는 여러 가지)로 CPU로 변환한다. CPU는 당신이 사용한 언어, 탭 설정, 주석, 문체 강조, 변수 이름 등을 알려줄 수 있습니다. CPU는 모든 레지스터와 opcode 및 메모리 위치가 왜곡되는지를 알려주는 비트 스트림에 관한 것입니다. 코드로 작성된 많은 것들은 우리가 지정한 순서대로 CPU에 의해 소비되는 것으로 변환되지 않습니다. 우리의 C, C ++, C #, Lisp, Babel, 어셈블러 또는 실제가 아닌 이론이면서 작업의 성명서로 쓰여진 것. 보시다시피, 어셈블러 언어로도 얻을 수있는 것은 아닙니다.
나는 "불필요한 것들"(빈 줄과 같은)의 사고 방식을 이해하지만 "잡음과 혼란스런 코드 일뿐입니다." 저의 경력은 저였습니다. 나는 그것을 완전히 얻는다. 이 시점에서 나는 코드를 명확하게 만드는 방향으로 기울어진다. 내 프로그램에 50 줄의 "노이즈"를 추가하는 것과는 다릅니다. 여기 또는 저기에 몇 줄이 있습니다.
규칙에는 예외가 있습니다. 휘발성 메모리, 정적 메모리, 경쟁 조건, 싱글 톤, "오래된"데이터 사용 및 이와 같은 모든 종류의 썩음 현상이있는 시나리오에서는 다른 점이 있습니다. 자신의 메모리를 관리해야하며, 메모리가 일부가 아니기 때문에 잠금 및 무효화가 필요합니다. GC'd Universe - 잘하면 모두가 그것을 이해합니다. 나머지 시간은 GC'd 언어로되어있어 필요성이나 성능 향상이 아닌 스타일의 문제입니다.
하루가 끝나면 GC 자격 요건에 대해 이해하고 있는지 확인하십시오. 적절하게 잠금, 처리 및 무효화; 왁스를 켜고 왁스를 내린다. 숨을들이 쉬고 내쉬세요; 그리고 내가 말하는 모든 것에 대해 : 기분이 좋으면 그것을하십시오. 귀하의 마일리지가 달라질 수 있습니다 ...
어떤 객체는.dispose()
메모리에서 리소스를 강제로 제거하는 메서드입니다.