United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4864304 Improve memory consumption of Swing apps
JDK-4864304 : Improve memory consumption of Swing apps

Details
Type:
Bug
Submit Date:
2003-05-15
Status:
Resolved
Updated Date:
2003-07-26
Project Name:
JDK
Resolved Date:
2003-07-26
Component:
client-libs
OS:
solaris_9,solaris_8,solaris_2.6,solaris_7,linux,generic,solaris_10,windows_xp
Sub-Component:
javax.swing
CPU:
x86,sparc,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.0,5.0
Fixed Versions:
5.0 (tiger)

Related Reports
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
There are a number of changes that could be done to Swing/AWT to
improve the memory footprint:

. Rewrite Autoscroller.
. Promote a handful of methods from JComponent to Container.
. Move seldomly used fields to a separate data structure.

                                    

Comments
EVALUATION

Yes.
This needs to be more fully investigated to determine the impact and the
best bang for the buck.
###@###.### 2003-05-14

The following was done:
SwingGraphics has been nuked.
setXXXSize and isXXXSizeSet have been promoted to Component
Removed EnableSerialization hack from JComponent, Component now has a
  hack.
DebugGraphics is now only loaded when necessary.
Rewrote Autoscroller
Rewrote OverlayLayout to SharedOverlayLayout so that it can be shared
  and NOT cache anything.
Removed JComponent._bounds, uses getX, getY, getWidth and getHeight
  now.
Removed AbstractButton.accessibleIcon, not needed.
Promoted JButton.defaultCapable to AbstractButton to avoid an extra
  field.
Removed JLabel.accessibleIcon
Made JComponent.alignmentX/alignmentY floats vs Float.
Removed JComponent.paintImmediatelyClip and tmpRect, instead a cache
  of Rectangles is kept. 
Made clientProperties into an ArrayTable.
Made the following into client properties: htmlView, ancestorNotifier,
  transfer, inputVerifier.
JScrollPane/MetalScrollPaneUI/BasicScrollPaneUI tweaks to allow for a
  null horizontal scrollbar
JPopupMenu calls enableEvents instead of adding a MouseListener.
Combined actions that ToolTipManager creates into a UIAction.
MetalInternalFrameTitle no longer sets the accessible names of the
  icons, instead this is a promoted to basic and basic now overrides
  getAccessibleContext.

This resulted in the following API changes:
This request consists of five distinct changes.
 
The first is promoting setXXXSize and isXXXSizeSet methods from JComponent to
Component. This is done to reduce redundancy of fields between JComponent and
Component. This resulted in the following new methods to Component:
    /**
     * Sets the preferred size of this component to a constant
     * value.  Subsequent calls to <code>getPreferredSize</code> will always
     * return this value.  Setting the preferred size to <code>null</code>
     * restores the default behavior.
     *
     * @param preferredSize The new preferred size, or null
     * @see #getPreferredSize
     * @see #isPreferredSizeSet
     * @since 1.5
     */
    public void setPreferredSize(Dimension preferredSize);
 
 
    /**
     * Returns true if the preferred size has been set to a
     * non-<code>null</code> value otherwise returns false.
     *
     * @return true if <code>setPreferredSize</code> has been invoked
     *         with a non-null value.
     * @since 1.5
     */
    public boolean isPreferredSizeSet();
 
    /**
     * Sets the minimum size of this component to a constant
     * value.  Subsequent calls to <code>getMinimumSize</code> will always
     * return this value.  Setting the minimum size to <code>null</code>
     * restores the default behavior.
     *
     * @param minimumSize the new minimum size of this component
     * @see #getMinimumSize
     * @see #isMinimumSizeSet
     * @since 1.5
     */
    public void setMinimumSize(Dimension minimumSize);
 
    /**
     * Returns whether or not <code>setMinimumSize</code> has been
     * invoked with a non-null value.
     *
     * @return true if <code>setMinimumSize</code> has been invoked with a
     *              non-null value.
     * @since 1.5
     */
    public boolean isMinimumSizeSet();
 
    /**
     * Sets the maximum size of this component to a constant
     * value.  Subsequent calls to <code>getMaximumSize</code> will always
     * return this value.  Setting the maximum size to <code>null</code>
     * restores the default behavior.
     *
     * @param maximumSize a <code>Dimension</code> containing the
     *               desired maximum allowable size
     * @see #getMaximumSize
     * @see #isMaximumSizeSet
     * @since 1.5
     */
    public void setMaximumSize(Dimension maximumSize);
 
    /**
     * Returns true if the maximum size has been set to a non-<code>null</code>
     * value otherwise returns false.
     *
     * @return true if <code>maximumSize</code> is non-<code>null</code>,
     *               false otherwise
     * @since 1.5
     */
    public boolean isMaximumSizeSet();
 
 
  These properties will fire a property change event when they are
  changed (they are bound). We will document this in Component's
  addPropertyChangeListener method. This will result in adding the
  following to addPropertyChangeListener's javadoc:
 
     *    <li>this Component's preferred size ("preferredSize")</li>
     *    <li>this Component's minimum size ("minimumSize")</li>
     *    <li>this Component's maximum size ("maximumSize")</li>
     *    <li>this Component's name ("name")</li>
 
 
This resulted in removing the following 3 methods from JComponent (they are now inherited):
    /**
     * Returns true if the minimum size has been set to a non-<code>null</code>
     * value otherwise returns false.
     *
     * @return true if <code>minimumSize</code> is non-<code>null</code>,
     *               false otherwise
     * @since 1.3
     */
    public boolean isMinimumSizeSet();
 
    /**
     * Returns true if the preferred size has been set to a
     * non-<code>null</code> value otherwise returns false.
     *
     * @return true if <code>preferredSize</code> is non-<code>null</code>,
     *               false otherwise
     * @since 1.3
     */
    public boolean isPreferredSizeSet();
 
    /**
     * Returns true if the maximum size has been set to a non-<code>null</code>
     * value otherwise returns false.
     *
     * @return true if <code>maximumSize</code> is non-<code>null</code>,
     *               false otherwise
     * @since 1.3
     */
    public boolean isMaximumSizeSet();
 
 
To improve memory needed for autoscrolling it was necessary for JComponent to
override the processMouseEvent method, the spec will read:
    /**
     * Processes mouse events occurring on this component by
     * dispatching them to any registered
     * <code>MouseListener</code> objects, refer to
     * {@link java.awt.Component#processMouseEvent(MouseEvent)}
     * for a complete description of this method.
     *
     * @param       e the mouse event
     * @see         java.awt.Component#processMouseEvent
     * @since       1.5
     */
    protected void processMouseEvent(MouseEvent e);
 
 
To optimize the heap size of AbstractButton we need to override a couple
of methods from the superclass, they are:
    /**
     * Adds the specified component to this container at the specified
     * index, refer to
     * {@link java.awt.Container#addImpl(Component, Object, int)}
     * for a complete description of this method.
     *
     * @param     comp the component to be added
     * @param     constraints an object expressing layout constraints
     *                 for this component
     * @param     index the position in the container's list at which to
     *                 insert the component, where <code>-1</code>
     *                 means append to the end
     * @exception IllegalArgumentException if <code>index</code> is invalid
     * @exception IllegalArgumentException if adding the container's parent
     *                       to itself
     * @exception IllegalArgumentException if adding a window to a container
     * @since 1.5
     */
    protected void addImpl(Component comp, Object constraints, int index);
 
    /**
     * Sets the layout manager for this container, refer to
     * {@link java.awt.Container#setLayout(LayoutManager)}
     * for a complete description of this method.
     *
     * @param mgr the specified layout manager
     * @since 1.5
     */
    public void setLayout(LayoutManager mgr);
 
The remaining changes clarify specification that was documenting implementation
when it should not have been. These changes allow us to reduce the per instance
size of JButtons and JViewports.
 
javax.swing.AbstractButton.createChangeListener was documenting implementation
details. Change the @return from:
 
     * @return the new <code>ButtonChangeListener</code>
     */
    protected ChangeListener createChangeListener();
 
to:
 
     * @return a <code>ChangeListener</code>
     */
    protected ChangeListener createChangeListener();
 
javax.swing.JViewport.createLayoutManager was documenting implementation
details. Change the javadoc from:
 
    /**
     * Subclassers can override this to install a different
     * layout manager (or <code>null</code>) in the constructor.  Returns
     * a new <code>ViewportLayout</code> object.
     *
     * @return a <code>LayoutManager</code>
     */
    protected LayoutManager createLayoutManager();
 
to:
 
    /**
     * Subclassers can override this to install a different
     * layout manager (or <code>null</code>) in the constructor.  Returns
     * the <code>LayoutManager</code> to install on the <code>JViewport</code>.
     *
     * @return a <code>LayoutManager</code>
     */
    protected LayoutManager createLayoutManager();

I've attached two files that show the difference in instance size of various swing widgets. The 1.4.2 file is relative to 1.4.2 and includes some other tuning that was done as part of the Synth work. The 1.5 file is relative to b8 of tiger.
Size calculation was done by creating one instance of a particular widget and taking a snapshot of the heap, then creating 11 instances and calculating the delta and dividing 10.
###@###.### 2003-07-25
                                     
2003-07-25
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
tiger

FIXED IN:
tiger

INTEGRATED IN:
tiger
tiger-b13


                                     
2004-06-14



Hardware and Software, Engineered to Work Together