빌더(TWx) 님이 쓰신 글 :
: 100jk 님이 쓰신 글 :
: : 빌더(TWx) 님이 쓰신 글 :
: : : 100jk 님이 쓰신 글 :
: : : : 아래와 같은 소스가 있습니다.
: : : :
: : : : var
: : : : b, b2: Tbitmap;
: : : : begin
: : : : b := tbitmap.create;
: : : : b2 := b;
: : : : b.free; //비트맵해제
: : : : //{이곳에 판단식을 넣고싶습니다.}
: : : : b2.free; //당연히 에러
: : : :
: : : : b2를 해제하기 전에 b2주소에 있는 비트맵(혹은 다른 클래스)이 이미 해제되어있는 상태인지
: : : :
: : : : 판단할 수 있는 방법이 있나요?
: : :
: : :
: : :
: : : 답변:
: : :
: : :
: : :
: : : 할당되어 있던 메모리가 해제 됐는지 아닌지는 델파이 메모리 매니지먼트 내부구조를 이해하고 있으면
: : : 간단하게 알아 낼 수 있습니다.
: : :
: : : memory management 내부구조는 델파이 버전에 따라 다를 수 있어서...
: : : 설치되어 있는 rad 10.3.1 기준으로 설명합니다.
: : :
: : :
: : : function IsFreed(var obj ): Boolean;
: : : begin
: : : Result := PULONG_PTR(PByte(obj) - sizeof(ULONG_PTR))^ and 1 <> 0;
: : : end;
: : :
: : : procedure TForm1.Button1Click(Sender: TObject);
: : : var b1, b2: TBitmap;
: : : begin
: : : b1 := TBitmap.Create;
: : : b2 := b1;
: : :
: : : b1.Free;
: : : if IsFreed(b2) then
: : : Memo1.Lines.Add('b2 freed.');
: : : end;
: : :
: : :
: : :
: : :
: : : 위와 같이 처리하면 할당되어 있던 메모리의 해제여부를 쉽게 알아 낼 수 있습니다만...
: : :
: : : std::shared_ptr 이용해서 C++로 코딩하면 공유 메모리 관리에 신경 쓸 일이 없지요.
: : :
: :
: : 예전부터 정말 궁금했던 내용인데 답변 정말 감사드립니다.
: :
: : 윈도우에서 정상작동 하는걸 확인했습니다.
: :
: : 혹시 FMX에서도 해당내용이 구현이 가능할까요?
: :
: : PULONG_PTR, ULONG_PTR 등이 winapi.windows에 정의 되어있어 다른 플랫폼에서는
: :
: : 해당 기능이 구현이 컴파일이 안되네요.
: :
:
:
: 답변:
:
:
: 델파이 FMX 안드로이드 플렛폼 메모리 매니지먼트 관련해서 다시 질문하는 것 같은데...
:
: 델파이 FMX 메모리 매니지먼트 구조는 결론부터 말하면 실패작 입니다.
:
: 안드로이드 코어파트가 Java 프레임웍으로 구현되어 있고...
: 델파이 컴파일러는 리눅스 플렛폼에서 사용되는 확장자 .so 라이브러리를(프로젝트 이름이 test 이면 libTest.so)
: 생성하고 Android SDK 에서 제공되는 Java 클래스 라이브러리를 Activity로 연계해서 실행될 수 있는 구조로
: 타겟을 만들어 내는데...
:
: 즉, Java 클래스 .dex 파일과 네이티브 형식의 바이너리인 .so 라이브러리 파일이 연계해서 동작는 구조.
:
: 델파이 하나만 사용하는 사람들 보면 메모리 릭이 발생할 때... 문제의 모든 원인은 Java VM 때문이다 라고
: 황당한 말을 하는 사람들이 있던데
:
: 델파이 코드에서 할당되는 메모리는 Java VM으로 부터 할당되는 게 아니고
: 리눅스 플렛폼에서의 libc 표준 C 런타임 API 이용해서 VM이 아닌 native memory pool 로 부터
: 별개로 할당된다는 기초적인 파이어몽키 아키텍쳐 조차 모르고 있으니 그런 황당한 소리를 하는 거겠죠.
:
:
: FMX의 메모리 매니지먼트 내부코드는 ARC(Automatic Reference Count)를 이용해서 구현되어 있습니다.
:
: Java 의 경우 메모리 관리를 VM에서 자동으로 관리해 주니까...
: native memory pool 로 부터 할당받는 메모리도 우아하게 Java 처럼 자동으로 관리할 수 있게 하기위해
: ARC 를 도입했던 건데.
:
: Java는 컴파일러와 프레임웍을 처음 설계할 때 부터 Modern memory management 아키텍쳐를 염두해 두고 만들어진 반면에
: 델파이 컴파일러와 RTL/VCL 프레임웍은 애초부터 legacy 아키텍쳐 베이스로 만들어진 구조라서 문제가 발생할 여지가 다분함에도
: 불구하고... 속된 말로 겉멋을 부려서 똥폼을 잡은 거죠.
:
:
: 델파이 ARC 메모리 매니지먼트 구조는 앞으로 나올 10.4 버전에서 폐기될 겁니다. (델파이 로드맵 확인해 보세요)
: 지금의 구조로는 ARC 처리가 잘못되면 메모리 릭으로 이어질 수 밖에 없어요.
: 메모리 릭을 피할려면 사용자가 일일히 strong, weak 포인터 처리를 해줘야 하고
:
:
: 할당된 어떤 객체가 포인터에 대한 크로스 레퍼런스 관계를 갖고있으면...
: DisposeOf()를 호출해도 destructor가 한번 실행되지만, 메모리가 바로 해제 된다는 보장을 하지 못합니다.
:
: 메모리가 disposed 되어있는 상태(zombie 상태)만 알 수 있는 거죠.
:
: 이전 글에서 답변했던 방법을...
: 델파이 FMX 파이어몽키 ARC 메모리 모델에선 적용할 수 없어요.
:
:
답변 정말 감사드립니다. 답변들이 정말 엄청나시네요. 받아먹기 힘든 제 지식이 안타깝네요.
혹시 이런건 가능한지 여쭤봐도 되나요?
var
b1, b2: tbitmap;
begin
b1 := tbitmap.create;
b2 := b1;
여기서 b2가 자기가 생성자로 생성된 놈인지 아니면 다른곳에서 생성된 클래스를 참조만 하는놈인지 알 수 있는 방법이 있나요?
(목표는 클래스를 알아서 정리해주는 모듈을 제작해보고 싶습니다)