Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to efficiently manage memory using Strings?

Tags:

Consider a sample piece of code.

public void testString() {          int i = 0;     while(i < 100000000)     {         String s ="Hi hello bye" +i;         i++;               } } 

In each iteration, a new String is created and its value is no longer needed for the next iteration. I tried printing the memory consumed pre and post this testString() functionality. Here are their values.

Before invoking testString():  Total Memory: 91684864 (87.4375 MB) Max Memory:   1360855040 (1297.8125 MB) Free Memory:  72163552 (68.82052612304688 MB)  After invoking testString(): Total Memory: 424280064 (404.625 MB) Max Memory:   1360855040 (1297.8125 MB) Free Memory:  171766816 (163.80960083007812 MB). 

I see a large amount of memory being used and am afraid JVM Heap may go out of bounds due to the current way of handling Strings. The String generated for iteration 1 is no longer needed in iteration 2 and its storage space can be freed. I believe that is not happening here.

I tried using StringBuffer and StringBuilder objects and there seems a very marginal improvement in the memory usage.

Kindly assist me a better and optimal approach.

like image 229
Vignesh Avatar asked Apr 30 '14 05:04

Vignesh


People also ask

Do strings take up a lot of memory?

In the current implementation at least, strings take up 20+(n/2)*4 bytes (rounding the value of n/2 down), where n is the number of characters in the string. The string type is unusual in that the size of the object itself varies. The only other classes which do this (as far as I know) are arrays.

How are string saved in memory explain with example?

Strings are stored on the heap area in a separate memory location known as String Constant pool. String constant pool: It is a separate block of memory where all the String variables are held. String str1 = "Hello"; directly, then JVM creates a String object with the given value in a String constant pool.

How much memory does a string use?

An empty String takes 40 bytes—enough memory to fit 20 Java characters.

Does string make Java more memory efficient?

Answer: String literal makes java more memory efficient.


2 Answers

The String generated for iteration 1 is no longer needed in iteration 2 and its storage space can be freed. I believe that is not happening here.

It definitely is happening.

You're creating 100 million strings, each of which is at least 13 characters - and most of which will be about 20 characters. Each string consists of an object (which has overhead) and a char[] - so I'd guess at it taking around 60 bytes for a 20-character string.

If garbage collection weren't being effective, 100 million objects requiring 60 bytes each would require 6GB - whereas you're seeing a total memory which is only about 300MB larger than it was to start with.

The strings are being collected - just not immediately.

You haven't told us what you need to do with the strings in your real code (I'm assuming there's a real motivation for this) - assuming you actually need a string in each iteration of a loop, I don't think using StringBuilder is going to help you. If you only need the data is a StringBuilder then you can make it a lot more efficient, but it's rare that you create a StringBuilder but don't call toString on it.

like image 129
Jon Skeet Avatar answered Oct 17 '22 07:10

Jon Skeet


What will happen on the first run

JVM runs the code, generates the strings, and at certain intervals the Garbage Collector frees the used memory. Beside some wasted execution time, the program will run normally.

What will happen if the function is called frequently

JVM will begin to optimize the loop, realize that nothing is done with those strings ever and marks the entire function as dead code. Eventually calling the function will do literally nothing, as the JVM converted the content to a simple return

Kindly assist me a better and optimal approach.

Since even the JVM has no clue what your code is supposed to do... what is it what you want to do? There might be an optimal solution for your actual problem at hand, that is very different from the code sample that you posted initially.

like image 22
TwoThe Avatar answered Oct 17 '22 09:10

TwoThe