문제를 처리 한 후 체계. 루시아노 (Luciano)와 후안 (Juan)의 해답 (논평에서)은 매우 흥미 롭긴하지만 인스턴스 동작을 사용하지 않았습니다. 여기에 내가 테스트를 위해 사용하고 코드입니다 :
testFinalizationReleasesExternalMemory
" WeakArray restartFinalizationProcess "
| handles |
handles := (1 to: 11) collect: [:i |
Smalltalk garbageCollect.
APIStatus create getHandle].
self assert: (handles asSet size) < 11.
예에서이 #create
포인터 (create
외부 API에서 오는 이름) 메모리를 할당하고 반환하는 외부 함수에 FFI 호출을 사용 :
여기
create
| answer |
answer := ExternalAPI current createStatus.
self finalizationRegistry add: answer.
^answer
ExternalAPI
는 #createStatus
는 APIStatus
에 대한 메모리를 할당하고 그것의 포인터를 반환하는 API 호출되면, FFI 인터페이스입니다. 마무리에
나는 메모리를 복원 API를 호출 #deleteStatus:
다시 메모리를 해제 API 호출입니다
delete
self finalizationRegistry remove: self ifAbsent: [].
self library deleteStatus: self.
handle := nil.
.
이 테스트에서는 외부 라이브러리가 사용 가능 해지면 메모리를 재사용한다고 가정합니다. 특히 새로 할당 된 블록의 크기가 이전과 동일 할 경우에만 사용합니다. 이것은 오늘날 대부분의 경우에 맞지만 적어도 뭔가 새로운 것을 배우는 것이 아니라면이 테스트가 실패하는 것을보고 싶습니다.
테스트는 11 개의 외부 구조를 할당하고 포인터를 저장하고 다음 매크로를 할당하기 전에 각 매크로의 메모리를 해제 한 다음 포인터 중 하나가 반복되는지 비교합니다. 나는 왜 10 포인터를 좋은 숫자로 사용하기로 결정했는지 모르겠다. 2는 충분해야하지만, 메모리 할당 알고리즘은 때로는 까다 롭다.
니스. 그러나 이것은 finalization을 사용하고 @gera는 _testing_ finalization을 위해 필요한 것을 알고 있어야합니다. –
아니요, 파이널 라이즈를 사용하지 않습니다. –
아! 우수한. 나는 그것이 복사 된 클래스를 없애 버릴 줄 알았다. –