FIX: Java.awt.PrintJob Leaks GDI Objects (277781)



The information in this article applies to:

  • Microsoft virtual machine

This article was previously published under Q277781

SYMPTOMS

When you use PrintJob objects that are returned by the Toolkit.getPrintJob method, you may notice memory and Graphics Device Interface (GDI) handle leaks. The symptoms are as follows:
  • On Microsoft Windows 95 or Microsoft Windows 98, GDI resource percentages drop indefinitely as seen with the Resource Meter.
  • On Microsoft Windows NT, GDI handles rise indefinitely as seen with the Task Manager.

CAUSE

This problem is caused by a bug in the Microsoft virtual machine's (Microsoft VM) PrintJob and PrintGraphics implementation that sometimes keeps a PrintGraphics object from properly cleaning up after itself.

RESOLUTION

To resolve this issue, install build 3319 or later of the Microsoft VM. For more information, visit the following Microsoft Web site:WARNING: After you install the updated Microsoft VM, you cannot uninstall it.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

This bug was corrected in the Microsoft VM build 3319.

MORE INFORMATION

Steps to Reproduce Behavior

  1. Create a file named PrintTestRepro.java, and paste the following code:
    import java.awt.*;
    import java.awt.event.*;
    
    public class PrintTestRepro extends Frame {
    
       public PrintTestRepro () {
          Button myButton = new Button("Print");
          Drawing myDrawing = new Drawing();
    
          setLayout(new BorderLayout(5, 5));
          setSize(300, 300);
    
          add(myButton, BorderLayout.SOUTH);
    
          myDrawing.setLayout(new GridLayout(3,3,40,40));
          add(myDrawing, BorderLayout.CENTER);
    
          for (int i = 0; i < 9; i++) {
             myDrawing.add(new Drawing());
          }
    
          myButton.addActionListener(new ActionListener() {
             public void actionPerformed (ActionEvent evt) {
                try {
                   PrintJob job = 
                      Toolkit.getDefaultToolkit().getPrintJob(null, "", null);
                   print(job.getGraphics());
                   job.end();
                   System.gc();
                }
                catch (Throwable e) {
                   System.out.println(e);
                }
             }
          });
    
          addWindowListener(new WindowAdapter() {
             public void windowClosing (WindowEvent evt) {
                System.exit(0);
             }
          });
    
          setVisible(true);
       }
    
       public static void main (String[] args) {
          new PrintTestRepro();
       }
    
       class Drawing extends Container {
    
          public void paint (Graphics g) {
             Dimension sz = getSize();
    
             for (int x = 0; x < sz.width; x++) {
                int s = (int) (x * 255.0 / sz.width);
                g.setColor(new Color(s, s, s));
                g.drawLine(x, 0, x, sz.height);
             }
    
             super.paint(g);
          }
    
          public Dimension getPreferredSize () {
             return new Dimension(100, 100);
          }
       }
    }
    					
  2. At a command prompt, type the following line to compile the sample:

    jvc PrintTestRepro

  3. At a command prompt, type the following line to run the sample:

    jview PrintTestRepro

  4. At the bottom of the application, click the Print button, and print to a file or printer.

    Observe the GDI resources:
    • On Windows 95 or 98, GDI resource percentages drop indefinitely as seen with the Resource Meter.
    • On Windows NT, GDI handles rise indefinitely as seen with the Task Manager.

REFERENCES

For support information about Visual J++ and the SDK for Java, visit the following Microsoft Web site:

Modification Type:MajorLast Reviewed:6/14/2006
Keywords:kbAwtPkg kbBug kbfix kbJavaVM33xxfix KB277781