Soru Ara bağlamaları JavaFX 8'de toplanan çöplerden korumak için önerilen yaklaşım nedir?


TL; DR: GC aktif bağlarımı yiyor.

Java 7'de JavaFX 2.2'yi kullanarak geliştirilmiş ve başarıyla dağıtılmış bir uygulama var.

JavaFX 8.0'a (ve Java 8) geçiş yaptığımda / geçiş yaptığımda, bazı özellikler istisnalar ya da hatalı durum değişikliği ile ilgili diğer belirtiler olmaksızın "gizemli bir şekilde" çalışmayı durdurur - orta uygulama yaşam döngüsü ". Örneğin; düğmeler çalışmayı durdurur, özel hücre oluşturucuları uygulanmaya son verildi, etkin / devre dışı bırakılmış durum güncellemeyi durdurdu.

Birkaç saat süren kazma işleminden sonra, JavaFX 8'de bazı değişiklikler olduğunu ve iç kullanımının problemi anladığını düşünüyorum. javafx.beans.WeakListener JavaFX 2.2'de bulunan bellek sızıntılarıyla uğraşmak. Temel olarak, veri bağımlılığını yönetmek için oluşturduğum bağlantıların, NodeKontrol ettikleri hala aktif.

Anonim sınıfları kullanarak bağlamaları başlattığımda sorunlar çoğunlukla ortaya çıkıyor gibi görünüyor. Benim sorunumun tamamı değil ama bazıları, bir sınıf üyesi olarak bağlanmaya bir referans kaydedilerek, böylece GC'nin toplanmasını engelleyerek sabitlenebilir. Bütün kontrolörler GC'leri aldılar, çünkü bunlar FXML yüklemesiyle başlatıldı ve doğrudan referans alınmadı (şimdi her zaman ana düğümdeki denetleyiciye bir referans gönderiyorum) userData mülkiyet).

Benim sorunlarım:

  1. ilişkili hatalar deterministik olmayan bir şekilde ortaya çıkar (ya da en azından hafıza ayak izi fonksiyonudur)
  2. eğer anonim sınıflar olsa da bağlayıcılar engellenirse, bunu değiştirmek için büyük, mevcut bir kod tabanında her örneği bulmak çok iştir.
  3. her örneği bulabildiysem bile, kodu çok fazla karıştırıyor

Hayal kırıklığıyla, Oracle belgelerinde "anonim sınıflarla bağlama oluşturma" ya da bağlayıcıların güvenilir şekilde kullanılmasını sağlamak için başka herhangi bir yönerge bulunmadığını göremiyorum. Orada bir çok kod örneği var. kullanım anonim sınıf bağlamaları. JavaFX 2.2 uygulamasını JavaFX 8'e doğru şekilde nasıl güncelleyeceğine dair herhangi bir not da bulamadım.

Gelişen insanlardan herhangi bir tavsiye Önemsiz olmayan JavaFX uygulamaları büyük beğeni topluyor (3 yıldır JavaFX 2.x uygulamaları geliştiriyorum ve 15 yıldır Swing uygulamaları geliştirdim), bu yüzden tam olarak bir n00b sorusu değil).


Not: Benim sorum benzer Temiz JavaFX özellik dinleyicileri ve bağlamaları (bellek sızıntıları)ama karmaşık bağları nasıl kullanacağımı ve kesin olarak nasıl bildiğimi bilmek ve her örnekle ilgili referanslarla kirletici sınıflara başvurmadan rastgele zamanlarda çöplerin toplanmamasını sağlamak istiyorum.


19
2018-01-29 13:48


Menşei


(JavaFX 8'deki değişiklikler ve javafx.beans.WeakListener'ın iç kullanımları ile ilgili) birazcık detaylandırırsanız, bunların farkında olmamak (toplanan, fx öncesi 8'e çok derinlemesine bakmayı reddetti ;-); Bağlamalar her zaman (ve hala) bir baş belasıydı ... - kleopatra
Basit bir örnek arayanlar için bkz. bu soru. Yapmak istediğiniz şey, ona dayanan herhangi bir UI öğesi ile aynı olan herhangi bir bağlama yaşam döngüsünü oluşturmaktır (bu zor olacaktır). - James_D
Evet, sadece test edildi ve diğer soruda "kayıp bağlamalar" sorunu hem JavaFX 2.2 hem de JavaFX 8'de ortaya çıkıyor gibi görünüyor. - James_D
Kuşkusuz, benim kodun 2.x'te çalışması gerçeği kırmızı bir ringa olabilir; GC davranışı ve bellek ayak izi, bir fark yaratmak için Java 8'de yeterince farklı olabilir. - metasim
Bu tür uyarıları dokümanlarda bulamadığınız için beni şaşırtmıyor. Bu, bir kimsenin zayıf dinleyicilerin etkilerini düşündüğü anlamına gelir ve birileri bunun hakkında düşünürse, zayıf dinleyiciler fikri hemen düştü. Ama hey, keşke JavaFX tasarımındaki tek kötü fikir olsaydı… - Holger


Cevaplar:


WeakEventHandler -supposed- dinleyici nesnesinin GC'sine izin vermek içindir (aksi belirtilmedikçe) ve sadece o anda çalışmayı durdurur. Bulunduğunuz gibi, bu, tetikleyiciyi tutmak için ihtiyaç duyduğunuz sürece işleyiciye başvurmanız gerektiği anlamına gelir. Bu gereksinim, anonim bir sınıf kullanıp kullanmayacağınız konusunda az çok bağımsızdır; normal bir sınıf kullanırsanız aynı şekilde başarısız olur.

Gelecekte belirli bir olayın tetiklenmeyeceğini "otomatik olarak" belirlemenin hiçbir yolu yoktur, bu da aslında bu sorunun "düzeltilmesi" için gereken bir özelliktir. Bir şey istemediyseniz, tüm anonim dinleyicileri bir yerdeki statik değişken olarak saklanan bir listeye ekleyebilirsiniz. Eğer GC'nin çalışmasını istiyorsanız (ve sonunda yapacaksanız), sadece gerekli olduğunda referansları koruyarak ve artık onları bırakmadan kontrol etmek zorunda kalacaksınız.


3
2018-03-09 00:53