-
Bug
-
Resolution: Won't Fix
-
P4
-
None
-
1.1.6
-
x86
-
windows_95
On Wndows/95 the enclosed code causes an out of memory with the scree color depth set to 16 or 24. On windows/NT it uses vittual memory. This on machines with 32 to 60MB of memory. Usinf -ms or -mx seems to quite ineffective in increasing the space available for creating an image.
<applet code="ImageTest2.class" width=300 height=300></applet>
<p>
-----------
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class ImageTest2 extends Applet implements ActionListener {
Image m_OffScreen = null;
Graphics m_OffG = null;
Button m_Button = null;
public void init( ) {
m_Button = new Button( "press to test");
m_Button.addActionListener( this);
setLayout( null);
m_Button.setBounds( 10, 125, 280, 50);
add( m_Button);
}
public void actionPerformed( ActionEvent ae) {
System.out.println("\nBase line: create huge image");
Runtime rt = Runtime.getRuntime();
long freeMemBeforeLoading = rt.freeMemory();
System.out.println("\nFree memory before creating image: " + freeMemBeforeLoading);
int width = 3072;
int height = width;
System.out.println("\nWidth: " + width + " Height: " + height);
System.out.println("Expected size of image at 8 Bits: " + (width * height));
System.out.println("Expected size of image at 16 Bits: " + (width * height * 2));
System.out.println("Expected size of image at 24 Bits: " + (width * height * 3) + "\n");
m_OffScreen = createImage( width, height);
long freeMemAfterLoading = rt.freeMemory();
long memoryUsed = freeMemBeforeLoading - freeMemAfterLoading;
System.out.println("\nFree memory after creating image: " + freeMemAfterLoading);
System.out.println("\nMemory used by creating image: " + memoryUsed);
m_OffG = m_OffScreen.getGraphics( );
remove( m_Button);
System.gc( );
repaint( );
}
public void paint( Graphics g) {
if( m_OffScreen != null) {
m_OffG.setColor( Color.blue);
m_OffG.fillRect( 0, 0, 300, 300);
g.drawImage( m_OffScreen, 0, 0, this);
}
else {
super.paint( g);
}
}
}
-----------
<applet code="ImageTest3.class" width=300 height=300></applet>
<p>
-----------
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class ImageTest3 extends Applet implements ActionListener {
Image m_Huge = null;
Button m_Button = null;
public void init( ) {
m_Button = new Button( "press to test");
m_Button.addActionListener( this);
setLayout( null);
m_Button.setBounds( 10, 125, 280, 50);
add( m_Button);
}
public void actionPerformed( ActionEvent ae) {
System.out.println("\nBase line 'huge.gif' at 8 Bits");
Runtime rt = Runtime.getRuntime();
long freeMemBeforeLoading = rt.freeMemory();
System.out.println("\nFree memory before loading image: " + freeMemBeforeLoading);
m_Huge = getImage( getCodeBase( ), "huge.gif");
boolean notDisplayed = false;
while ( (m_Huge.getWidth(this) == -1) && (m_Huge.getHeight(this) == -1) ) {
if (!notDisplayed) {
System.out.println("\nLoading image...");
notDisplayed = true;
}
}
int width = m_Huge.getWidth(this);
int height = m_Huge.getHeight(this);
System.out.println("\nWidth = " + width);
System.out.println("Height = " + height);
System.out.println("Expected raw size of image = " + (width * height) + " bytes");
MediaTracker aTracker = new MediaTracker( this);
aTracker.addImage( m_Huge, 0);
try {
aTracker.waitForAll( );
}
catch( Exception e) {
e.printStackTrace( );
System.exit( 0);
}
aTracker = null;
remove( m_Button);
System.gc( );
repaint( );
}
public void paint( Graphics g) {
if( m_Huge != null) {
g.drawImage( m_Huge, 0, 0, this);
}
else {
super.paint( g);
}
}
}
------------------------
Here is some additional information from the customer that characterizes the problem even better:
ImageTest2 uses createImage to make Image objects of 3072x3072 pixels.
ImageTest3 uses getImage to make Image objects of 3072x3072 pixels. It loads "huge.gif", also included in the ZIP file.
I tested this on a Windows 95 machine and a Windows NT machine in 8 bpp, 16 bpp, and 24 bpp. On Windows 95 I used the System Monitor ("Allocated Memory"). On Windows NT I used the Task Manager ("MEM Usage" under the
"Performance" tag).
ImageTest3 Win95 8bpp: 9 megs
ImageTest3 Win95 16bpp: 18 megs
ImageTest3 Win95 24bpp: 27 megs
Note that this is EXACTLY as I have been saying in another (tangentially related) message-thread. The GIF image should only take 9 megs uncompressed because it is a 8bpp format. But the image memory used in Win32 (I do not know if this is a Java issue or a Win32 issue, but I suspect Win32) is based on the bit-depth of the display.
Note also that ImageTest3 DOES NOT crash.
ImageTest2 Win95 8bpp: 9 megs
ImageTest2 Win95 16bpp: CRASH immediately upon hitting the test button
ImageTest2 Win95 24bpp: CRASH immediately upon hitting the test button
Ok, in ImageTest2 we try to create an image of 3072x3072 (same size as in ImageTest3!!!) rather than load it. We can't. At least, not on Windows 95 at bit-depths higher than 8.
In our e-mail discussions on 20-May-98 and 21-May-98 we realized that there is a memory issue rather than a bit-depth issue. By checking out various combinations of image sizes and bit-depths, you found that the following were limits on Windows 95:
4087x4088 at 8bpp
2890x2890 at 16bpp
2360x2360 at 24bpp
I then showed you that the following amounts of memory were used:
4087x4088 at 8bpp = 16,707,656 bytes
2890x2890 at 16bpp = 16,704,200 bytes
2360x2360 at 24bpp = 16,708,800 bytes
When you added a pixel, you got crashes. Again, I pointed out the memory
usage:
4088x4088 at 8bpp = 16,711,744 bytes
2891x2890 at 16bpp = 16,709,980 bytes
2361x2360 at 24bpp = 16,715,880 bytes
So, Windows 95 doesn't seem to be able to support an Image that uses more than a certain amount of memory. The exact value is yet to be determined (it would need some more trial-and-error) but seems to be somewhere between 16,708,800 and 16,709,980 bytes (at ANY bit depth).
Ahhh... but IS there really such a limit? We saw that ImageTest3 was very happy loading Images which used much more memory than this. The second test used 18 megs and the third used 24 megs.
This is the crux of my argument. It seems that the "approximately 16 meg" limitation exists only for createImage and NOT for getImage. So there is no actual limitation on the size of the Image data - only a limitation on the size of the Image data that createImage can handle.
Now, Windows NT...
ImageTest3 WinNT 8bpp: 9 megs
ImageTest3 WinNT 16bpp: 18 megs
ImageTest3 WinNT 24bpp: 27 megs
The same behavior as Win 95. Now let's try ImageTest2.
ImageTest2 WinNT 8bpp: 9 megs
ImageTest2 WinNT 16bpp: 18 megs
ImageTest2 WinNT 24bpp: 27 megs
This is different than the Win 95 behavior. It is also the preferred behavior. I won't call it totally correct, because I would prefer that ImageTest3 only use 9 megs in each screen bit depth (in both OSes) because the original image is only 8 bpp. However, I am willing to live with that, as long as we can get the crashes to stop under ImageTest2 on Windows 95. This is a real problem.
I can only assume that when I sent ImageCrash.zip on 6-May-98 that I did not properly explain the issue and hope that this clarifies it. I apologize for any amount I have led you down inappropriate research paths. This issue is the paramount one. In fact, I believe that discovering the causes behind these issues may answer some of our other questions about memory usage of images.
<applet code="ImageTest2.class" width=300 height=300></applet>
<p>
-----------
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class ImageTest2 extends Applet implements ActionListener {
Image m_OffScreen = null;
Graphics m_OffG = null;
Button m_Button = null;
public void init( ) {
m_Button = new Button( "press to test");
m_Button.addActionListener( this);
setLayout( null);
m_Button.setBounds( 10, 125, 280, 50);
add( m_Button);
}
public void actionPerformed( ActionEvent ae) {
System.out.println("\nBase line: create huge image");
Runtime rt = Runtime.getRuntime();
long freeMemBeforeLoading = rt.freeMemory();
System.out.println("\nFree memory before creating image: " + freeMemBeforeLoading);
int width = 3072;
int height = width;
System.out.println("\nWidth: " + width + " Height: " + height);
System.out.println("Expected size of image at 8 Bits: " + (width * height));
System.out.println("Expected size of image at 16 Bits: " + (width * height * 2));
System.out.println("Expected size of image at 24 Bits: " + (width * height * 3) + "\n");
m_OffScreen = createImage( width, height);
long freeMemAfterLoading = rt.freeMemory();
long memoryUsed = freeMemBeforeLoading - freeMemAfterLoading;
System.out.println("\nFree memory after creating image: " + freeMemAfterLoading);
System.out.println("\nMemory used by creating image: " + memoryUsed);
m_OffG = m_OffScreen.getGraphics( );
remove( m_Button);
System.gc( );
repaint( );
}
public void paint( Graphics g) {
if( m_OffScreen != null) {
m_OffG.setColor( Color.blue);
m_OffG.fillRect( 0, 0, 300, 300);
g.drawImage( m_OffScreen, 0, 0, this);
}
else {
super.paint( g);
}
}
}
-----------
<applet code="ImageTest3.class" width=300 height=300></applet>
<p>
-----------
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class ImageTest3 extends Applet implements ActionListener {
Image m_Huge = null;
Button m_Button = null;
public void init( ) {
m_Button = new Button( "press to test");
m_Button.addActionListener( this);
setLayout( null);
m_Button.setBounds( 10, 125, 280, 50);
add( m_Button);
}
public void actionPerformed( ActionEvent ae) {
System.out.println("\nBase line 'huge.gif' at 8 Bits");
Runtime rt = Runtime.getRuntime();
long freeMemBeforeLoading = rt.freeMemory();
System.out.println("\nFree memory before loading image: " + freeMemBeforeLoading);
m_Huge = getImage( getCodeBase( ), "huge.gif");
boolean notDisplayed = false;
while ( (m_Huge.getWidth(this) == -1) && (m_Huge.getHeight(this) == -1) ) {
if (!notDisplayed) {
System.out.println("\nLoading image...");
notDisplayed = true;
}
}
int width = m_Huge.getWidth(this);
int height = m_Huge.getHeight(this);
System.out.println("\nWidth = " + width);
System.out.println("Height = " + height);
System.out.println("Expected raw size of image = " + (width * height) + " bytes");
MediaTracker aTracker = new MediaTracker( this);
aTracker.addImage( m_Huge, 0);
try {
aTracker.waitForAll( );
}
catch( Exception e) {
e.printStackTrace( );
System.exit( 0);
}
aTracker = null;
remove( m_Button);
System.gc( );
repaint( );
}
public void paint( Graphics g) {
if( m_Huge != null) {
g.drawImage( m_Huge, 0, 0, this);
}
else {
super.paint( g);
}
}
}
------------------------
Here is some additional information from the customer that characterizes the problem even better:
ImageTest2 uses createImage to make Image objects of 3072x3072 pixels.
ImageTest3 uses getImage to make Image objects of 3072x3072 pixels. It loads "huge.gif", also included in the ZIP file.
I tested this on a Windows 95 machine and a Windows NT machine in 8 bpp, 16 bpp, and 24 bpp. On Windows 95 I used the System Monitor ("Allocated Memory"). On Windows NT I used the Task Manager ("MEM Usage" under the
"Performance" tag).
ImageTest3 Win95 8bpp: 9 megs
ImageTest3 Win95 16bpp: 18 megs
ImageTest3 Win95 24bpp: 27 megs
Note that this is EXACTLY as I have been saying in another (tangentially related) message-thread. The GIF image should only take 9 megs uncompressed because it is a 8bpp format. But the image memory used in Win32 (I do not know if this is a Java issue or a Win32 issue, but I suspect Win32) is based on the bit-depth of the display.
Note also that ImageTest3 DOES NOT crash.
ImageTest2 Win95 8bpp: 9 megs
ImageTest2 Win95 16bpp: CRASH immediately upon hitting the test button
ImageTest2 Win95 24bpp: CRASH immediately upon hitting the test button
Ok, in ImageTest2 we try to create an image of 3072x3072 (same size as in ImageTest3!!!) rather than load it. We can't. At least, not on Windows 95 at bit-depths higher than 8.
In our e-mail discussions on 20-May-98 and 21-May-98 we realized that there is a memory issue rather than a bit-depth issue. By checking out various combinations of image sizes and bit-depths, you found that the following were limits on Windows 95:
4087x4088 at 8bpp
2890x2890 at 16bpp
2360x2360 at 24bpp
I then showed you that the following amounts of memory were used:
4087x4088 at 8bpp = 16,707,656 bytes
2890x2890 at 16bpp = 16,704,200 bytes
2360x2360 at 24bpp = 16,708,800 bytes
When you added a pixel, you got crashes. Again, I pointed out the memory
usage:
4088x4088 at 8bpp = 16,711,744 bytes
2891x2890 at 16bpp = 16,709,980 bytes
2361x2360 at 24bpp = 16,715,880 bytes
So, Windows 95 doesn't seem to be able to support an Image that uses more than a certain amount of memory. The exact value is yet to be determined (it would need some more trial-and-error) but seems to be somewhere between 16,708,800 and 16,709,980 bytes (at ANY bit depth).
Ahhh... but IS there really such a limit? We saw that ImageTest3 was very happy loading Images which used much more memory than this. The second test used 18 megs and the third used 24 megs.
This is the crux of my argument. It seems that the "approximately 16 meg" limitation exists only for createImage and NOT for getImage. So there is no actual limitation on the size of the Image data - only a limitation on the size of the Image data that createImage can handle.
Now, Windows NT...
ImageTest3 WinNT 8bpp: 9 megs
ImageTest3 WinNT 16bpp: 18 megs
ImageTest3 WinNT 24bpp: 27 megs
The same behavior as Win 95. Now let's try ImageTest2.
ImageTest2 WinNT 8bpp: 9 megs
ImageTest2 WinNT 16bpp: 18 megs
ImageTest2 WinNT 24bpp: 27 megs
This is different than the Win 95 behavior. It is also the preferred behavior. I won't call it totally correct, because I would prefer that ImageTest3 only use 9 megs in each screen bit depth (in both OSes) because the original image is only 8 bpp. However, I am willing to live with that, as long as we can get the crashes to stop under ImageTest2 on Windows 95. This is a real problem.
I can only assume that when I sent ImageCrash.zip on 6-May-98 that I did not properly explain the issue and hope that this clarifies it. I apologize for any amount I have led you down inappropriate research paths. This issue is the paramount one. In fact, I believe that discovering the causes behind these issues may answer some of our other questions about memory usage of images.