如何减少Java Swing表单的感知加载时间?

时间:2009-09-23 12:24:38

标签: java performance swing

在我的Swing应用程序中,我遇到的问题是,在第一次创建Swing表单的新实例时,需要几百毫秒。这不是很长,但减速的主观印象真的很烦人。

它适用于所有形式,甚至是JOptionPane消息或其他简单形式。 (当然,由于构造函数更复杂,更大的形式需要更长时间)

现在我注意到第二次创建新表单实例明显更快

由于初始启动时间并不重要,我计划在启动时创建所有重要表单的不可见实例,但这看起来像是一个肮脏的黑客。 (而且我不确定它是否会起作用)

我的问题:

  • 是否有更优雅的方式来加速表单的创建和显示?
  • 第一次显示表单时会发生什么,第二次不会发生?

2 个答案:

答案 0 :(得分:7)

由于您描述了JOptionPane发生的问题,因此在类加载中听起来很慢。您是否有机会通过网络加载?它也可能是垃圾收集,因为旧的窗户可以为新的窗户腾出空间。

我从垃圾收集开始,因为它很容易测试和纠正:在启动Java时使用-verbose:gc参数(必须从控制台执行此操作),并注意GC是否在这些暂停期间运行。如果是,请使用-Xmx增加内存分配,并可能按照here所述调整堆部分。

如果网络连接速度慢(并且像 strace 这样的工具可以帮助诊断这个),那么你需要预加载类(不实例化它们)。您可以使用 Class.forName()

在后台线程上执行此操作

除了这两个显而易见的事情之外,你还需要运行一个分析器来了解发生了什么。

答案 1 :(得分:4)

有关性能提示,请参阅this article。基本上,您希望将UI线程中完成的工作保持在最低限度,因为这会影响组件的呈现并使其感觉缓慢。

  

Swing应用程序有三种类型的线程:

     
      
  • 初始线程
  •   
  • UI事件派发线程(EDT)
  •   
  • 工作线程
  •   
     

每个应用程序都必须有一个表示其起点的main方法。此方法在初始或启动线程上运行。初始线程可能会读取程序参数并启动一些其他对象,但在许多Swing应用程序中,此线程的主要目的是启动应用程序的图形用户界面(GUI)。一旦GUI启动大多数事件驱动的桌面应用程序,初始线程的工作就完成了。

     

Swing应用程序只有一个用于UI的EDT。该线程通过调用应用程序的事件处理程序来绘制GUI组件,更新它们并响应用户交互。所有事件处理程序都在EDT上运行,您应该只在EDT上以编程方式与UI组件及其基本数据模型进行交互。在EDT上运行的任何任务都应该快速完成,以便您的UI响应用户输入。从其他线程访问UI组件或其事件处理程序将导致UI中的更新和绘图错误。在EDT上执行长时间运行的任务将导致应用程序无响应,因为GUI事件将在事件调度队列中累积。

根据评论进行更新,以下是其他一些要检查的内容:

您是否正在运行病毒扫描程序?在我的工作机器上,病毒扫描程序检查加载的所有jar文件的内容,这对启动时间有很大影响。如果可能,请尝试关闭病毒扫描程序或禁用该文件夹。

你是否在启动时加载额外的课程?理想情况下,您应该加载轻量级委托,只在第一次调用时加载实现(这是sWT中的常见做法,其中每个菜单项与轻量级委托关联,该委托实例化在需要时执行实际处理的类型)。您可以尝试分析应用程序以查看启动时创建的内容并相应地添加一些间接。