Memory problems with frequent conversions Integer.toString ()

I am currently porting a game developed in C # (for Windows Phone) to Java (Android).

We are having memory problems in the Java version, which after profiling seems to come from a huge number of String objects in memory, obviously due to the unchanging nature of String . Now I was able to trace this down to a method that displays the player on the screen, where Integer.toString() used every time the score changes (many times per second). I can’t use StringBuilder (this is what we have in the C # version) because the text rendering methods of the frame we use only accept String as arguments, so the conversion happens anyway.

Is this a common problem in Java? Can anyone recommend a solution (besides contacting the developers of the framework to ask them to change their methods!)?

Update:

The game is very fast, and the score is partially based on the time elapsed since the beginning of the current “stage”. It is updated 15 times per second.

We won’t refer to the line, but I think that perhaps the structure is leaking or duplicating these lines, so I am trying to study this (it is not a public structure and, as far as I know, it hasn’t been used for this kind of fast-paced game )

Unification is a good suggestion, and I thought about trying to do it, but the rating system must be changed to have a fixed set of values.

+4
source share
2 answers

We decided to solve this problem by creating our own modifiable string class, supported by a fixed-length char array, and creating our own methods for rendering text with zero distribution after initialization.

After that, everything went much more smoothly, but we still had a few “hangs” caused by the GC. After profiling, it turned out that this was due to the large number of iterators created in the loops during the main game loop. Then we wrote a custom array class that uses an iterator pool, and now everything works fine!

0
source

I'm not sure if this helps in your particular case, but in general, when you have a fixed set of fixed string values ​​that you work with, it makes sense to add all of them to the pool pool. In this case, you can force the JVM not to create objects on the heap for each new row, but to use a row pool.

You will need to modify your code to return rows from the pool, for example, for example:

 return String.valueOf(123).intern(); 

Some additional explanation from javadoc:

When the intern method is called, if the pool already contains a string equal to this String object, as determined by the equals (Object) method, the string from the pool is returned. Otherwise, this String object is added to the pool and a reference is returned to this String object.

+2
source

All Articles