简体   繁体   English

JavaFX 8隐藏阶段时内存泄漏

[英]JavaFX 8 Memory leak when Hiding Stage

I have a JavaFX application that minimizes to tray when the X button is pressed. 我有一个JavaFX应用程序,当按下X按钮时,该应用程序最小化到托盘。 I have been monitoring the application via VisualVM for memory trends. 我一直在通过VisualVM监视应用程序的内存趋势。

The weird part is, when the application is open, or minimized to taskbar, the memory is always GCed back to initial memory used. 奇怪的是,当应用程序打开或最小化到任务栏时,内存总是被GC返回到使用的初始内存。 However, when it is minimized to tray ( stage.hide() , systemTray.show() ), the memory gets GCed, but in an upward trend (leak). 然而,当它被最小化到托盘( stage.hide() systemTray.show()时,存储器获取GCed,但在向上的趋势(泄漏)。

In VisualVM, the Old Gen space keeps going up, and once it hits the max after some time, the application will be unresponsive, and CPU spikes to 80%. 在VisualVM中,Old Gen空间不断上升,一旦它在一段时间后达到最大值,应用程序将无法响应,并且CPU峰值达到80%。

I notice that if I stage.show() on the app by double clicking the tray icon etc, GC will clear everything back to normal . 我注意到如果我通过双击托盘图标等在应用程序上stage.show() ,GC将清除所有内容恢复正常 However, if left for prolonged periods, it will simply fail to GC the old gen. 但是,如果长时间离开,它将无法使GC成为老一代。

A heap dump shows javafx.scene.Scene#7 and javafx.scene.Node[]#2 as having the most retained space. 堆转储显示javafx.scene.Scene#7javafx.scene.Node[]#2具有最多的保留空间。 Both will not appear if the stage is not hidden. 如果未隐藏舞台,则两者都不会出现。 Under references, it shows this[] -> dirtyNodes() . 在引用下,它显示了this[] -> dirtyNodes()

this     - value: javafx.scene.Node[] #2
<- dirtyNodes     - class: javafx.scene.Scene, value: javafx.scene.Node[] #2
 <- value     - class: javafx.scene.Node$ReadOnlyObjectWrapperManualFire, value:  
 javafx.scene.Scene #7

What is causing this and how can I solve this? 造成这种情况的原因是什么?如何解决这个问题?

I never did find and answer to this. 我从来没有找到并回答这个问题。 Instead, I would null the node on hide and restore it back on view. 相反,我会在隐藏上隐藏节点并在视图上恢复它。 For intensive dynamic nodes/multiple nodes I created a hash map to store them in memory. 对于密集的动态节点/多个节点,我创建了一个哈希映射来将它们存储在内存中。

This has sort of become a habit for me in javafx8 to dispose all graphics and reassign on hide & view from hash map. 这有点习惯于我在javafx8中处理所有图形并重新分配隐藏和查看哈希映射。 The extra memory and cpu usage is negligible on modern desktops. 在现代桌面上,额外的内存和CPU使用率可以忽略不计。 Using this method, I have had 0 cpu usage apps and low memory apps (~100m) running when hidden on win8/10. 使用这种方法,我在win8 / 10上隐藏了0个cpu使用应用程序和低内存应用程序(~100m)。

Java has features Like Weak Reference: https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html Java具有类似弱参考的功能: https//docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html

Soft reference: https://docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html 软参考: https//docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html

these allow you to specifically target the VM ->> what to garbage collect. 这些允许您专门针对VM - >>垃圾收集的内容。

also, there is Concurrency API http://winterbe.com/posts/2015/04/07/java8-concurrency-tutorial-thread-executor-examples/ 还有,并发API http://winterbe.com/posts/2015/04/07/java8-concurrency-tutorial-thread-executor-examples/

that that uses Executor Service and Thread Pooling. 那使用Executor Service和Thread Pooling。

and for memory restrictive Applications in java the Software should call 对于java中的内存限制应用程序,软件应该调用

System.gc() // garbage collector

at Intervals irrespective to its automatic invocation 在Intervals,无论其自动调用

You can use the Runtime class to schedule the Load Balancers for the project https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html 您可以使用Runtime类为项目安排Load Balancers https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

public Process exec(String command)


                throws IOException
//--------------------------------------------------------
    Executes the specified string command in a separate process.

public void gc()

//----------------------------------------------------------
Runs the garbage collector. Calling this method suggests that the Java virtual machine expends effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the virtual machine has made its best effort to recycle all discarded objects
This is a convenience method. An invocation of the form exec(command) behaves in exactly the same way as the invocation exec(command, null, null). 

threading has always been a problem with memory intensive applications and within JavaFX every component of a scene are threads tightly bound to a Scene but as of the implementation, it seems to to be Loosely bound. 对于内存密集型应用程序,线程一直是个问题,而在JavaFX中,场景的每个组件都是紧密绑定到场景的线程,但是在实现时,它似乎是松散绑定的。

If there is a long running required its better to Handle some of the processor intensive tasks in the Native side(JNI). 如果需要长时间运行,则可以更好地处理Native端(JNI)中的一些处理器密集型任务。 Moreover, a CLEAN architecture would Benefit 此外,CLEAN架构将受益

https://www.google.co.in/webhp?sourceid=chrome-instant&rlz=1C1CHBF_enIN736IN736&ion=1&espv=2&ie=UTF-8#q=clean+code& * https://www.google.co.in/webhp?sourceid=chrome-instant&rlz=1C1CHBF_enIN736IN736&ion=1&espv=2&ie=UTF-8#q=clean+code& *

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM