HI, I have a small application, that has two JTextArea controls. I load some files (sometimes as big as 20 mb) to one of them, do some processing and write the result to the other JTextArea control. I have set the JVM size as 64. This is fine with small files. But the problems on hand are: 1. If I load a file and start processing, the Memory Usage goes up. Even after 10 mins. of the process completion it's not coming down. 2. If I clear the JTextArea controls, then also the Memory usage is not coming down. So, over all the Memory usage is always goes up! Afterwards if I attempt to load a file or do something else, OutOfMemoryError occurs. If I change the JVM size to something around 256 or 512 then its OK. Bu t we cannot force this change on customer's machine as it may effect other appls. running. I am using threads for loading of the files and the other processing. I think, I'm taking all the necessary care to close the file pointers and nullify the other objects in the methods. But still, this problem persisits. Any info or suggestions in this regard is highly appreciated. Thanks.
You'll need to be a little more precise in your language. How are you measuring "memory usage?" Using Runtime.freeMemory() or using your operating system's tools? If it's the latter, you should know that the way Sun's JVMs work is that that allocated memory is never returned to the OS -- i.e., you'll never see the process size shrink, only grow, until the process terminates. Even if all the Java memory is freed, it's returned to the Java heap, not to the OS. Now, as far as memory leaks go: there are tools, both commercial and free, which help you track leaks down. You need to determine what objects are being leaked. Finally, note that a 20MB text file uses 40MB as a string in memory (characters are 16bit in Java), and I don't know what the processing involves, but processing that much text in a 64MB Java heap, it would be easy to run out of room. I have no idea how "changing the JVM size" could affect other applications on the machine -- it's just a command-line switch that you'll apply to your one program, so if you determine that there really isn't a leak, but you just need more than 64MB of heap, then just add the switch to the command line for your application, and it will have no effect on anything else.
Mmmm, do you have more info, Tony? The only reference I could find to this was here. That was over three years ago. I know that an assortment of memory leaks in Swing have been fixed over time. Is there any reason to think this one is still around? "All strings are pooled" sounds rather extreme; I doubt this happens to all strings that are used anywhere in Swing, for example. Of course I could be completely wrong. Any additional info would be appreciated.
I once ran into a surprising String problem due to the way the substring method works. I had one huge String from which I grabbed a small substring - in spite of the fact that the reference to the huge String was discarded, all of the characters were kept in memory because the substring is constructed using a reference to the char array of the huge String plus an offset and length. Thus any substring of the huge String caused the char to be referenced and kept in memory. The solution is to copy the desired characters to a new char and make the new String from that. Bill
posted 15 years ago
Yeah. It turns out that the new String(String) constructor will do this for you too, without having to explicitly make a separate char array. Though this isn't documented. (Then again, nothing about size of backing arrays is documented it seems.) Still, since that constructor has no other practical use I can think of, it's nice to know it does something. See also this discussion.
"I'm not back." - Bill Harding, Twister
Author and all-around good cowpoke
posted 15 years ago
Jim - After posting that, I went digging in the String source and found the discussion of that constructor. If they had just stuck one more sentence into the JavaDocs about how the characters were copied it would have been a LOT more helpful. Oh well ..... use the source young programmer. Bill
Are you wrapping your input stream with a buffered reader? I think I remember reading something that said it's better to use the buffered reader instead of the other readers when working with big files. Maybe it handles the memory better... Anyways, I'm no expert on this matter, but it might be worth a try Another thing I read recently and it's kind of scary is a bug with the grid bag layout, which uses a bunch of fixed size arrays (512 ints and doubles) to hold info... See it on Sun's bug parade, it's not even fixed yet http://developer.java.sun.com/developer/bugParade/bugs/4254022.html
posted 14 years ago
Actually they say it's fixed, it's just not released yet (planned for 1.5).