Niezawodna metoda czyszczenia zewnętrznego zasobu powiązanego z obiektem

Konkretny przypadek użycia: istnieje abstrakcja danych binarnych, która jest powszechnie używana do obsługi binarnych plam o dowolnym rozmiarze. Odkąd abstrakcja powstała bez zastanowienia się nad rzeczamina zewnątrz VM, istniejące implementacje polegają na garbage collector dla ich cyklu życia.

Teraz chcę dodać nową implementację, która używa pamięci masowej poza stosem (np. W pliku tymczasowym). Ponieważ istnieje wiele istniejącego kodu, który korzysta z abstrakcji, wprowadzenie dodatkowych metod zarządzania jawnym cyklem życia jest niepraktyczne, nie mogę przepisać każdego przypadku użycia klienta, aby zapewnić, że zarządzają nowymi wymaganiami cyklu życia.

Mogę pomyśleć o dwóch podejściach do rozwiązania, ale nie mogę zdecydować, które z nich jest lepsze:

a.) Użycie finalizacji () do zarządzania cyklem życia powiązanego zasobu (np. plik tymczasowy jest usuwany w finalizacji. Towydaje się bardzo prosty do wdrożenia.

b.) Użycie kolejki referencyjnej i java.lang.Reference (ale która, słaba lub fantomowa?) z dodatkowym obiektem, który usuwa plik, gdy odniesienie jest kolejkowane. Wydaje się, że implementacja jest nieco bardziej skomplikowana, musiałbym stworzyć nie tylko nową implementację, ale oddzielić jej dane czyszczeniai upewnij się, że obiekt czyszczenia nie może być GC przed obiektem, który został wystawiony użytkownikowi.

c.) Jakąś inną metodę, o której nie wspomniałem?

Jakie podejście powinienem podjąć (i dlaczego miałbym je preferować)? Wskazówki dotyczące wdrożenia są również mile widziane.

Edycja: Wymagany stopień niezawodności - w moim przypadku jest to całkowicie w porządku, jeśli jest to plik tymczasowynie wyczyszczone w przypadku nagłego przerwania maszyny wirtualnej. Główną troską jest to, że podczas pracy VM może bardzo dobrze wypełnić dysk lokalny (w ciągu kilku dni) plikami tymczasowymi (tak stało się ze mną w przypadku Apache TIKA, który tworzył pliki tymczasowe podczas wyodrębniania tekstu z niektórych typów dokumentów sprawcami były pliki zip). Mam zaplanowane okresowe czyszczenie na maszynie, więc jeśli plik spadnie po oczyszczeniu, nie oznacza to końca świata - o ile nie zdarza się to regularnie w krótkich odstępach czasu.

O ile mogłem określić, finalize () współpracuje z Oracale JRE. I jeśli poprawnie zinterpretuję javadocs, Referencjemusi działa zgodnie z dokumentacją (nie ma możliwości, aby tylko słabo / słabo osiągalny obiekt referencyjny nie został wyczyszczony przed wygenerowaniem OutOfMemoryError). Oznaczałoby to, że podczas gdy maszyna wirtualna może zdecydować się nie odzyskiwać określonego obiektu przez długi czas, musi to zrobić najpóźniej, gdy sterta się zapełni. To z kolei oznacza, że ​​na stercie może istnieć tylko ograniczona liczba moich obiektów typu blob. Maszyna wirtualna musi je w pewnym momencie oczyścić, inaczej zabrakłoby pamięci. A może istnieje jakaś luka, która pozwala maszynie wirtualnej na uruchamianie OOM bez usuwania odniesień (zakładając, że nie są one już silnie odwoływane)?

Edit2: O ile widzę to w tym momencie, zarówno finalize (), jak i Reference powinny być wystarczająco wiarygodne dla moich celów, ale zbieram Reference może być lepszym rozwiązaniem, ponieważ jego interakcja z GC nie może ożywić martwych obiektów, a tym samym ich wydajności wpływ powinien być mniejszy?

Edit3: Rozwiązania oparte na rozwiązaniu VM lub uruchamianiu (hak zamykający lub podobne) nie są dla mnie przydatne, ponieważ zazwyczaj VM działa przez dłuższy czas (środowisko serwera).

questionAnswers(4)

yourAnswerToTheQuestion