문제

VB6 양식 중 하나에서 다른 여러 양식 개체를 만들어 멤버 변수에 저장합니다. 라코 디스

이 (부모) 양식이 생성되고 파괴 될 때마다 메모리가 누출되고 있음을 알았습니다.이 멤버 변수를 NothingForm_Unload()에 할당해야합니까?

일반적으로 언제 필요합니까?

해결 :이 특정 메모리 누수는 문제의 양식에 대해 유전자 태그 코드를 수행했을 때 수정되었으며, 양식을 유전자 태그 코드로 설정했을 때가 아닙니다.클래스 모듈의 일부 인스턴스를 Unload로 명시 적으로 설정하여 몇 가지 다른 메모리 누수를 제거했습니다.

도움이 되었습니까?

해결책

@Matt Dillard-메모리 누수를 수정하지 않도록 설정 했습니까?

VB6에는 @Konrad Rudolph가 말한 내용에 따라 공식적인 가비지 수집기가 없습니다.

실제로 양식에 대해 unload를 호출하는 것이 기본 양식을 정리하고 각 하위 양식이 작업을 정리하도록하는 가장 좋은 방법 인 것 같습니다.

빈 프로젝트와 두 개의 빈 양식으로 이것을 테스트했습니다. 라코 디스

실행 후 두 양식이 모두 표시됩니다.frm을 nothing으로 설정하는 것이 잘되었습니다 ... 아무것도.

frm을 아무것도 설정하지 않으면이 양식에 대한 유일한 핸들은 참조를 통해 열립니다. 라코 디스

문제가 올바르게 표시됩니까?

  • 조시

다른 팁

실제로 VB6는 C ++처럼 RAII 를 구현합니다. 즉, 로컬에서 선언 된 참조가 자동으로 Nothing로 설정됨을 의미합니다.블록 끝에.마찬가지로 Class_Terminate를 실행 한 후 멤버 클래스 변수를 자동으로 재설정 해야 합니다.그러나 이것이 안정적으로 이루어지지 않는다는보고가 여러 차례있었습니다.엄격한 테스트는 기억 나지 않지만 멤버 변수를 수동으로 재설정하는 것이 항상 모범 사례였습니다.

@ 마틴 <인용구> <인용구>

VB6에는 C # .NET의 Using () 문과 "같이"작동하는 "With / End With"문이 있습니다.물론 글로벌 항목이 적을수록 더 좋습니다.

With / End With는 Using 문처럼 작동하지 않으며 문 끝에 "Dispose"가 없습니다.

With / End With는 VB.Net에서와 마찬가지로 VB 6에서도 작동하며 기본적으로 객체 속성 / 메서드 호출을 바로 가기하는 방법입니다.예 :

고객과 함께 .FirstName="John" .LastName="스미스" 종료

VB의 개체에는 참조 횟수가 있습니다. 이는 객체가 참조를 보유하고있는 다른 객체 변수의 개수를 유지한다는 것을 의미합니다. 객체에 대한 참조가 없으면 객체는 가비지 수집됩니다 (결국). 이 프로세스는 COM 사양의 일부입니다.

보통 로컬로 인스턴스화 된 객체가 범위를 벗어나면 (즉, 하위를 종료하면) 참조 카운트가 1 씩 감소합니다. 즉, 객체를 참조하는 변수가 파괴됩니다. 따라서 대부분의 경우 Sub를 종료 할 때 객체를 Nothing으로 명시 적으로 설정할 필요가 없습니다.

다른 모든 경우에는 참조 횟수 (1 씩)를 줄이려면 객체 변수를 Nothing으로 명시 적으로 설정해야합니다. 개체 변수를 Nothing으로 설정해도 개체가 반드시 삭제되는 것은 아니며 모든 참조를 Nothing으로 설정해야합니다. 이 문제는 재귀 적 데이터 구조에서 특히 심각 할 수 있습니다.

또 다른 문제는 객체 변수 선언에서 New 키워드를 사용할 때입니다. 개체는 New 키워드가 사용되는 시점이 아니라 처음 사용할 때만 생성됩니다. 선언에서 New 키워드를 사용하면 참조 횟수가 0이 될 때마다 처음 사용할 때 개체가 다시 만들어집니다. 따라서 객체를 Nothing으로 설정하면 객체가 파괴 될 수 있지만 다시 참조하면 객체가 자동으로 다시 생성됩니다. 이상적으로는 New 키워드를 사용하지 말고 이러한 부활 동작이없는 New 연산자를 사용하여 선언해야합니다.

엄밀히 말하면 절대 안되지만 가비지 컬렉터에게 청소를위한 강력한 힌트를 제공합니다.

원칙 : 만든 개체로 작업을 마칠 때마다 수행 합니다.

VB6 참조를 Nothing으로 설정하면 VB가 해당 객체에 대해 갖는 참조 수가 감소합니다.개수가 0 인 경우에만 개체가 삭제됩니다.

Nothing으로 설정했다고해서 .NET 에서처럼 "가비지 수집"이 될 것이라고 생각하지 마십시오.

VB6는 참조 카운터를 사용합니다.

C / C ++ 코드 등을 참조하는 인스턴스화 된 객체를 "없음"으로 설정하는 것이 좋습니다.VB6를 만진 지 오래되었지만 파일과 리소스를 아무것도 설정하지 않은 것을 기억합니다.

두 경우 모두 (이미 Nothing이면) 아프지는 않지만 객체가 파괴된다는 의미는 아닙니다.

VB6에는 C # .NET의 Using () 문과 "같이"작동하는 "With / End With"문이 있습니다.물론 글로벌 항목이 적을수록 더 좋습니다.

두 경우 모두 큰 개체를 만드는 것이 참조를 유지하고 재사용하는 것보다 비용이 더 많이 든다는 점을 기억하세요.

오랜만에 이와 비슷한 문제가있었습니다.앱이 종료되는 것을 막을 것 같지만 여기에서 적용 할 수 있습니다.

이전 코드를 가져 왔는데 다음과 같이 보입니다. 라코 디스

m_frm1을 언로드하는 것이 더 안전 할 수 있습니다.아무것도 설정하지 않습니다.

아직 언급되지 않은 한 가지 중요한 점은 객체 참조를 Nothing으로 설정하면 객체에 대한 다른 참조가없는 경우 (클래스가 VB로 작성된 경우 Class_Terminate) 객체의 소멸자가 실행된다는 것입니다 (reference카운트는 0).

경우에 따라 특히 RAII 패턴을 사용할 때 종료 코드가 오류를 발생시킬 수있는 코드를 실행할 수 있습니다.나는 이것이 일부 ADODB 클래스의 경우라고 생각합니다.또 다른 예는 파일 i / o를 캡슐화하는 클래스입니다. Class_Terminate의 코드는 파일이 아직 열려있는 경우 파일을 플러시하고 닫으려고 시도 할 수 있으며 이로 인해 오류가 발생할 수 있습니다.

따라서 객체 참조를 Nothing으로 설정하면 오류가 발생할 수 있으며 그에 따라 처리 할 수 있다는 점을 인식하는 것이 중요합니다 (예를 들어 "On Error Resume Next"를 삽입하여 이러한 오류를 무시할 수 있습니다."Set ...= Nothing"직전).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top