我制作了一个包含JButton的JFrame(称为J1
)。单击该按钮时,将打开一个新的JFrame(称为J2
)。J1
还有一个ArrayList,其中包含J2
和所有其他打开的Jframe。J2
设置为DISPOSE_ON_CLOSED
我为J2
设置了一个windowClosed()方法。为了进行测试,我在JFrame中循环抛出了ArrayList
,直到到达刚刚关闭的当前J2
,而且当我执行J2.setVisisble(true)
时,令人惊讶的是,J2
窗口返回了!
我还检查了任务管理器,并看到尽管打开了一个新的J2
,将使整个程序消耗更多的RAM,关闭每个J2
在任务管理器上并没有太大的区别,看起来任何内存被释放。几秒钟后,内存消耗似乎恢复为“正常”,因此我怀疑这与J2
有直接关系。
我尝试在每次启动新的System.out.print
时打印(ArrayList
)所有J2
内容,并且在打开一个窗口,将其关闭并打开一个新窗口之后,得到以下消息:
home.ATMmachine[frame0,252,198,620x420,invalid,hidden,layout=java.awt.BorderLayout,title=ATM Machine No.1,resizable,normal,defaultCloseOperation=DISPOSE_ON_CLOSE,rootPane=javax.swing.JRootPane[,9,38,602x373,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]
这意味着
J2
尚未完全删除!JFrame
dispose()
方法应该释放此Window及其子组件及其所有子级使用的所有本机屏幕资源。也就是说,这些组件的资源将被销毁,它们消耗的任何内存将返回给OS,并将它们标记为不可显示。
所以我是错的,并且在相加时间之后删除了该帧。
如果不是,那么我如何以引用该框架就像引用为null的方式删除该框架?
最佳答案
我制作了一个包含JButton的JFrame(称为J1)。单击该按钮时,将打开一个新的JFrame(称为J2)。 J1还有一个包含J2和所有其他打开的Jframe的ArrayList。 J2设置为DISPOSE_ON_CLOSED我为J2设置了一个windowClosed()方法。为了进行测试,我在JFrame内循环抛出ArrayList,直到到达刚刚关闭的当前J2,而且令人惊讶的是,当我执行J2.setVisisble(true)时,J2窗口返回了!
关闭JFrame并进行处理不会破坏JFrame对象,而是会释放系统资源,即在OS上显示窗口所需的资源。这与对象本身完全不同。当在已处置的JFrame上调用setVisible(true)
时,将重新创建资源,并重新显示窗口。这样就不会创建或销毁任何对象。
我还检查了任务管理器,并看到虽然打开了一个新的J2,将使整个程序消耗更多的RAM,关闭每个J2在任务管理器上没有太大的区别,看起来好像没有释放任何内存。几秒钟后,内存消耗似乎恢复到“正常”状态,因此我怀疑这与J2有直接关系。
毫不奇怪。
我尝试在每次启动新的J2时打印(System.out.print)所有ArrayList内容,并且在打开一个窗口,将其关闭并打开一个新窗口之后,得到以下消息:
home.ATMmachine [frame0,252,198,620x420,invalid,hidden,layout = java.awt.BorderLayout,title = ATM Machine No.1,可调整大小,正常,defaultCloseOperation = DISPOSE_ON_CLOSE,rootPane = javax.swing.JRootPane [,9,38,602x373 ,invalid,layout = javax.swing.JRootPane $ RootLayout,alignmentX = 0.0,alignmentY = 0.0,border =,flags = 16777673,maximumSize =,minimumSize =,preferredSize =],rootPaneCheckingEnabled = true]
这意味着J2尚未完全删除!
同样,您混淆了对象(只要存在对对象的引用)和资源,这些对象将一直存在。
JFrame dispose()方法应该
释放此Window及其子组件及其所有子级使用的所有本机屏幕资源。也就是说,这些组件的资源将被销毁,它们消耗的任何内存将返回给OS,并将它们标记为不可显示。
究竟。
所以我是错的,并且在相加时间之后删除了该帧。
只有当对象不再有更强的引用时,才可以对它进行GC处理,而垃圾回收器仅在感觉需要这样做时(例如,内存即将用完时)才进行GC处理。
如果不是,那么我如何以引用该框架就像引用为null的方式删除该框架?
就像其他任何对象一样。您可以在本地创建它,但是要小心,因为Swing侦听器可以创建强引用(您认为应该是弱引用),从而使对象持久存在的时间比您想要的长。
附带说明一下-为什么要使用所有JFrame?我使用的大多数程序都会给您带来很多烦人的窗口,我想这就是为什么我通常只看到新手程序员以这种方式创建它们的原因。为什么不使用CardLayout交换视图呢?
请查看:The Use of Multiple JFrames, Good/Bad Practice?以获得更多信息