The Artima Developer Community
Sponsored Link

Java Answers Forum
How to make program eat less memory/enhance performance ?

11 replies on 1 page. Most recent reply: Oct 21, 2003 12:23 PM by Matt Gerrans

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 11 replies on 1 page
David Smallwood

Posts: 1
Nickname: dave121
Registered: Oct, 2003

How to make program eat less memory/enhance performance ? Posted: Oct 15, 2003 7:47 AM
Reply to this message Reply
Advertisement
Dear experts,

I have a program that creates 3 tables containing series of line vectors. These are created from data contained in an ascii file. The program performs some calculations on the data. I have everything working perfectly i.e. it creates the tables, does the calculations and gives me the final results which I need (but this only happens when I use a data file that is 88Kb in size).

However, the frustrating problem I am experiencing currently is that when I use a heavier file e.g size 4.22mb, after a short delay, Windows starts complaining about memory errors and Windows task manager's Mem usage goes through the roof!

Eventually, I get an Exception in thread ?main? java.lang.OutOfMemoryError <<no stack trace available>> error from the JVM.

I have tried "java -Xrunhprof" command and it suggests that the real memory hogging line of code is:


name = ((String) v.elementAt(nj))+"\t"+((String) reference_vec.elementAt(nj));


As the program is dynamically allocating and creating a full nxn matrix of the input data lines at run-time that means it is creating zillions of strings at that line? Concatenation of Strings is not a good idea either as this blows performance too. I am thinking of re-writing the program in C. I have run out of ideas. Please can you suggest how I can make some tweaks to the java code so that the program runs more efficiently? Any comments welcome. Program is approx 500 LOC, can post on request.

d.


Senthoorkumaran Punniamoorthy

Posts: 335
Nickname: senthoor
Registered: Mar, 2002

Re: How to make program eat less memory/enhance performance ? Posted: Oct 15, 2003 8:40 PM
Reply to this message Reply
name = ((String) v.elementAt(nj))+"\t"+((String) reference_vec.elementAt(nj));


why don't you rewrite it like this
    StringBuffer concat = new StringBuffer();
    concat.append(v.elementAt(nj));
    concat.append("\t");
    concat.append(reference_vec.elementAt(nj));
    name = concat.toString();


Hope this improves your performance issue? Let me know how did it go :-)

sindu

Posts: 15
Nickname: sindu
Registered: Sep, 2003

Re: How to make program eat less memory/enhance performance ? Posted: Oct 15, 2003 11:37 PM
Reply to this message Reply
I read this from a book.So I feel its good if u can iniatialize the stringbuffer to a reasonable first guess.

"If the append method causes the size of the StringBuffer to grow beyond its current capacity, the StringBuffer allocates more memory. Because memory allocation is a relatively expensive operation, you can make your code more efficient by initializing a StringBuffer's capacity to a reasonable first guess, thereby minimizing the number of times memory must be allocated for it."

Also out of curiosity just want to know is it good to use append method as basically its going to convert it to a string and then append it.Dont this decrease performance?.If not can I pls know why??

zenykx

Posts: 69
Nickname: zenykx
Registered: May, 2003

Re: How to make program eat less memory/enhance performance ? Posted: Oct 19, 2003 2:19 PM
Reply to this message Reply
It is a really interesting post, cause everywhere you can read that the type of statement you used is optimized :(.
I think the solution is to use the suggested code.
I cannot explain exactly why you will get an improvement, but as everybody tells the StringBuffer append method is best suited for this kind of operations. It uses for convertion the following code:
(obj == null) ? "null" : obj.toString(), which doesn't really decrease the performance.

Senthoorkumaran Punniamoorthy

Posts: 335
Nickname: senthoor
Registered: Mar, 2002

Re: How to make program eat less memory/enhance performance ? Posted: Oct 20, 2003 12:15 AM
Reply to this message Reply
Also if the suggested code doesnt improve performance I still don't think going for C is a better alternative. Rather can use char[] as an alternative for string and may be create a class around char[] which is mutable and thus reduce the object creation. But then again there might be problems with threading I guess.

Lars Marius Garshol

Posts: 6
Nickname: larsga
Registered: Oct, 2003

Re: How to make program eat less memory/enhance performance ? Posted: Oct 20, 2003 5:27 AM
Reply to this message Reply
You are not providing enough information. However, you do provide one useful hint:

> As the program is dynamically allocating and creating a
> full nxn matrix of the input data lines at run-time that
> means it is creating zillions of strings at that line?

If your program does build an n x n matrix of the input where n is the number of lines in the input file it's clear that going from 88k to 4.2M should mean roughly 50 times as many lines, which again means 2500 times as much memory.

So the StringBuffer optimization tips you have been getting will make your program use less memory as it runs, but it will still produce a final matrix 2500 times bigger than for the 88k file...

Switching to C is likely to help, since C strings are by default 1 byte per character, whereas in Java they are 2 bytes per character. However, if we assume you can reduce memory consumption by a factor of 5 by switching you'll be down to 500 times as much memory as for the 88k file.

It may be that you have to change your approach to representing the matrix completely. How to do that, and whether it is possible I can't really tell without knowing what your program does.

Alexander Jerusalem

Posts: 36
Nickname: ajeru
Registered: Mar, 2003

Re: How to make program eat less memory/enhance performance ? Posted: Oct 20, 2003 12:16 PM
Reply to this message Reply
> Switching to C is likely to help, since C strings are by
> default 1 byte per character, whereas in Java they are 2
> bytes per character.

Lars, I'm not sure if you're right there. Doesn't Java use a UTF-8 representation internally? That would mean that at least all latin-1 characters are still only 1 byte, so I suppose switching to C wouldn't make a big difference.

Apart from that, I completely agree with your suggestion that a different matrix representation would be the way to go (depending on the problem of course) because if n can rise from 88K to 4.2M, it could probably rise even further, so the exponential growth rate might not be sustainable. Well again, it all depends on the specifics of the application...

Frank Mitchell

Posts: 37
Nickname: fmitchell
Registered: Jan, 2003

Re: How to make program eat less memory/enhance performance ? Posted: Oct 20, 2003 7:33 PM
Reply to this message Reply
[I thought I replied to this earlier, but the reply got eaten somehow.]

> Doesn't Java use a UTF-8 representation internally?

java.lang.String stores an array of 2-byte characters. JNI can convert strings to UTF-8, and of course I/O can write UTF-8, but the in-memory representation is UTF-16.

Similarly, I'm not sure porting to C will help. Yes, each string takes up half the bytes, but as someone above pointed out, the real problem is how memory consumption grows as the data set gets bigger.

Also, the suggested rewrite above, using StringBuffer, won't improve matters. The compiler already converts string concatenation into an expression using a StringBuffer.

My suggestions:

1. Defer converting elements in the matrix to Strings until the last possible moment. If possible, write the string representation directly to a Writer, and don't keep it afterwards.

2. If you're using the String as a hash key, create a class that contains references to the elements from which you compose the string, implement that wrapper's hashCode() and equals() methods, and use instances of that as a hash key. A quick if sub-optimal implementation of hashCode() would xor ("^") together the hash codes of each component referred to.

3. Read Jack Shirazi's book Java Performance Tuning, or check the website http://www.javaperformancetuning.com/. It's mostly about time optimization, but it also discusses space.

Senthoorkumaran Punniamoorthy

Posts: 335
Nickname: senthoor
Registered: Mar, 2002

Re: How to make program eat less memory/enhance performance ? Posted: Oct 20, 2003 10:31 PM
Reply to this message Reply
Something that can not be avoided as you guys have mentioned is the growth that will take place with the increase of file size.

But I think what is the real problem here is the number of intermediate String objects created inside the loop at the casting point.

If the StringBuffer solution doesn't solve that problem may the answer lies in tuning the garbage collection in such a way that intermediate objects are collected more frequently? Do you guys think that will solve the problem up to a certain extent?

http://java.sun.com/docs/hotspot/gc1.4.2/

http://www.javaworld.com/javaworld/jw-03-2003/jw-0307-j2segc_p.html

sindu

Posts: 15
Nickname: sindu
Registered: Sep, 2003

Re: How to make program eat less memory/enhance performance ? Posted: Oct 21, 2003 3:11 AM
Reply to this message Reply
This post is going interesting.

David,
Post ur code.It will help us to get to know more about memory optimization and also can help u solve ur problem.

Lars Marius Garshol

Posts: 6
Nickname: larsga
Registered: Oct, 2003

Re: How to make program eat less memory/enhance performance ? Posted: Oct 21, 2003 6:29 AM
Reply to this message Reply
> But I think what is the real problem here is the number of
> intermediate String objects created inside the loop at the
> casting point.

Clearly that is beside the point. Intermediate String objects to which no references are retained will be GC-ed, and if references to them *are* retained they will not be GC-ed. So GC tuning and StringBuffers will make no difference.

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: How to make program eat less memory/enhance performance ? Posted: Oct 21, 2003 12:23 PM
Reply to this message Reply
> This post is going interesting.
>
> David,
> Post ur code.It will help us to get to know more about
> memory optimization and also can help u solve ur problem.

Yeah, I suspect if it really does grow exponentially (or similarly) that the problem is in the algorithm, so it would help to have a look at it. There may be a Gordian Knot to chop...

Flat View: This topic has 11 replies on 1 page
Topic: Help me better Understand? Previous Topic   Next Topic Topic: JAVA

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use