vishnuc156 / hackerskeyboard

Automatically exported from code.google.com/p/hackerskeyboard
0 stars 0 forks source link

Investigate excessive memory use #64

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Got a report about Hacker's Keyboard sometimes being reported by the task 
manager as using 20-25MB of RAM on a Droid x², which seems excessive.

TODO: look where the memory is being used, and if there's a leak.

Note that memory usage is expected to be fairly high when a lot of input 
languages are enabled with multiple completion dictionaries, but in this case 
it's apparently English only with no extra dictionaries.

Original issue reported on code.google.com by Klaus.We...@gmail.com on 8 Aug 2011 at 11:31

GoogleCodeExporter commented 9 years ago
I can confirm that leaving Hacker's Keyboard as the selected input method for 
~24 hours on my Asus Eee Pad Transformer running the Prime 1.7 custom rom 
results in ~45mb memory usage and extreme sluggishness in all applications. 
Switching to another input method and back fixes the problem temporarily.

Original comment by Eternal...@gmail.com on 21 Aug 2011 at 8:21

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Forgot to mention, I too only use the English layout with no extra dictionaries.

Original comment by Eternal...@gmail.com on 21 Aug 2011 at 8:27

GoogleCodeExporter commented 9 years ago
Hm, so far I'm unsure what's going on, I've experimented a bit using the 
emulator but haven't figured out what's happening. The emulator is showing a 
Pss of 11.5M with about 2.2M from a 5M heap being in use, and this includes 
multiple dictionaries. The non-heap usage is higher than I'd have expected, but 
so far it appeared to be stable and not growing.

If you can reproduce the large increase, could you try running "dumpsys meminfo 
org.pocketworkstation.pckeyboard" on the device, or "adb shell dumpsys meminfo 
org.pocketworkstation.pckeyboard" via adb?

For comparison, here's the emulator output:

** MEMINFO in pid 334 [org.pocketworkstation.pckeyboard] **
                    native   dalvik    other    total
            size:    10920     5447      N/A    16367
       allocated:     8354     3115      N/A    11469
            free:      877     2332      N/A     3209
           (Pss):     2560     3325     5613    11498
  (shared dirty):     1808     3936     1320     7064
    (priv dirty):     2428     2044     4232     8704

The "allocated" and "Pss" lines would be helpful to see which memory area is 
growing.

Original comment by Klaus.We...@gmail.com on 21 Aug 2011 at 10:10

GoogleCodeExporter commented 9 years ago
A couple of questions for the bug reporters to

1. Do you have a large number of words in the user dictionary?

2. Do you make use of the voice input functionality?

3. If the issue is happening over time, then it could be that the "suggestions" 
code is leaking memory. Try turning suggestions off for a day and see if it 
helps. This is n't a workaround as doing this would be inconvenient for daily 
use but it will allow the developer to narrow down what to look at.

The following should be unchecked:

"Suggestions in landscape mode"
"Quick fixes"
"Show suggestions"
"Auto-complete"

Original comment by jcho...@gmail.com on 28 Aug 2011 at 4:48

GoogleCodeExporter commented 9 years ago
I've poked at .hprof files with MemoryAnalyzer for the keyboard running on my 
tablet, some preliminary results:

- it allocates temporary Canvas objects sized around 1.8M, presumably for the 
backing bitmap when the keyboard is drawn. I haven't seen in detail how often 
these get created, but I think it's plausible that these contribute to the 
total heap size being significantly larger than the active in-use size. These 
large byte arrays can stress the runtime due to fragmentation issues.

- the BinaryDictionary used for the completion dict uses about 800k, that's 
about as expected.

- the contacts dictionary uses about 500k on my system. It's plausible that 
really big contacts databases can make this much more significant.

- the user dictionary is negligible in size on my system, and I don't normally 
use voice entry, so I can't currently tell if those are a contributing factor. 

Overall I'm not really seeing a specific smoking gun pointing to a memory leak 
or obviously wasteful allocation.

Question for bug reporters - does the size keep growing, or does it settle down 
in a steady state at some point? Could you run the "meminfo" commant (see issue 
#4) and post results?

Some data from MemoryAnalyzer below.

Class Name                                                                      
       | Shallow Heap | Retained Heap
--------------------------------------------------------------------------------
--------------------------------------
org.pocketworkstation.pckeyboard.LatinIME @ 0x408df708                          
       |          456 |       858,032
|- mSuggest org.pocketworkstation.pckeyboard.Suggest @ 0x40ce2ad0               
       |           72 |       853,984
|- mContactsDictionary org.pocketworkstation.pckeyboard.ContactsDictionary @ 
0x408e5d08|           64 |       491,632
--------------------------------------------------------------------------------
--------------------------------------

Class Name                                                          | Shallow 
Heap | Retained Heap | Percentage
--------------------------------------------------------------------------------
--------------------------------
class android.content.res.Resources @ 0x4029d388 System Class       |           
40 |     2,425,840 |     23.75%
android.graphics.Canvas @ 0x41119540 Unreachable                    |           
40 |     1,817,728 |     17.79%
android.graphics.Bitmap @ 0x40773ae0                                |           
40 |     1,048,648 |     10.27%
org.pocketworkstation.pckeyboard.LatinIME @ 0x408df708              |          
456 |       858,032 |      8.40%
|- org.pocketworkstation.pckeyboard.Suggest @ 0x40ce2ad0            |           
72 |       853,984 |      8.36%
|  |- org.pocketworkstation.pckeyboard.BinaryDictionary @ 0x40d0f028|           
48 |       852,096 |      8.34%
--------------------------------------------------------------------------------
--------------------------------

Original comment by Klaus.We...@gmail.com on 29 Aug 2011 at 5:52

GoogleCodeExporter commented 9 years ago
I found a possible bug related to drawing popup previews, apparently those 
generate stack backtrace objects which get silently discarded without being 
logged, creating some garbage. Not sure if this is significant, but you may 
want to try turning off popups in the app's settings to see if this makes a 
difference.

I'll try to get back to investigating this, but if anyone else has ideas what 
may be going on I'd be happy for suggestions.

Original comment by Klaus.We...@gmail.com on 13 Oct 2011 at 5:16

GoogleCodeExporter commented 9 years ago
Progress. I'm currently rewriting the keyboard's redraw logic to avoid the need 
for using a backing bitmap for the keyboard graphics, and this should make a 
large difference in memory usage. I doubt that the bitmap did much for 
performance, but I'll need to do some testing if it has a noticeable impact.

Original comment by Klaus.We...@gmail.com on 15 Dec 2011 at 7:11

GoogleCodeExporter commented 9 years ago
If you're feeling experimental, try this version: 
http://code.google.com/p/hackerskeyboard/downloads/detail?name=hackerskeyboard-v
1028-experiment5.apk

It includes the refactored bitmap handling I mentioned in the previous update.

Original comment by Klaus.We...@gmail.com on 18 Dec 2011 at 1:18

GoogleCodeExporter commented 9 years ago
I added runtime render mode selection in revision 984825feded0, the new setting 
is available in version 1.28rc6 from 
http://code.google.com/p/hackerskeyboard/downloads/list. Please let me know if 
it makes a difference for you if you try it.

Setting the render mode to direct draw (unbuffered) appears to help according 
to MemoryAnalyzer, the unreachable objects no longer contain large bitmaps:

unreachable objects:
Class Name             | Objects | Shallow Heap
------------------------------------------------
byte[]                 |       6 |      190,384
char[]                 |      45 |        3,640
android.util.TypedValue|      68 |        2,720
java.lang.Character    |     105 |        1,680
...
------------------------------------------------
Total: 25 of 71 entries|     610 |      211,864
------------------------------------------------

There are still a few largish bitmaps left in the heap dump:
OQL> select * from android.graphics.Bitmap

Class Name                          | Shallow Heap | Retained Heap
-------------------------------------------------------------------
android.graphics.Bitmap @ 0x406f6450|           40 |     1,048,648
android.graphics.Bitmap @ 0x4056c788|           40 |       331,848
android.graphics.Bitmap @ 0x4084c280|           40 |       182,768
-------------------------------------------------------------------

I've written their mBuffer attributes to files and converted them to PNGs using 
ImageMagick based on the mWidth/mHeight attributes, with interesting results:
$ convert -size 512x512 -depth 8 rgba:buffer1.dat buffer1.png

Now I just need to figure out who allocates these bitmaps. The first one looks 
like a generic Honeycomb background, not sure about the others.

Original comment by Klaus.We...@gmail.com on 21 Dec 2011 at 11:45

Attachments:

GoogleCodeExporter commented 9 years ago
[Bulk bug update] The new Market release 1.29 includes the changes from the 
v1.28 prerelease series, and these "FixInTest" issues should now be fixed. If 
not, please reopen the bug with additional information. If the original bug 
covered multiple separate issues that aren't all addressed, please open new 
bug(s) for the leftover ones.

Original comment by Klaus.We...@gmail.com on 13 Jan 2012 at 9:29

GoogleCodeExporter commented 9 years ago
Hello,

I'm sorry to post in a closed thread but you seams to be the only one to talk 
about a problem i got.

First thanks for the explanation about dumping mBuffer and imagemagick it helps 
me see the bitmaps that haunts me.

I got like you 3 images left on the heap (in ICS the 2 first images takes 1MB 
each :(). and i can't understand where they comes from.

If you have found an explanation and solution and i can share you'll make me 
very happy.

Sorry again to use a comment in a closed issue.

Regards,
Tolriq.

Original comment by Tolriq on 18 Jan 2012 at 2:30

GoogleCodeExporter commented 9 years ago
Tolriq - haven't looked much further into what's going on with these bitmaps. 
Based on a quick scan of the ICS AOSP tree, the most likely culprits are these:

$ find base/ -name \*.png | xargs file | grep '512 x 512'
base/core/res/res/drawable-nodpi/background_holo_light.png:                     
          PNG image data, 512 x 512, 8-bit/color RGBA, non-interlaced
base/core/res/res/drawable-nodpi/background_holo_dark.png:                      
          PNG image data, 512 x 512, 8-bit/color RGBA, non-interlaced

So most likely one of the drawables uses this background by default, but I 
don't have any simple idea how to track it down. For now, I've mostly resigned 
myself to living with it, at least it appears to be a one-time allocation that 
doesn't strain the garbage collector as much as repeated allocation and 
deallocation would.

Original comment by Klaus.We...@gmail.com on 19 Jan 2012 at 1:46

GoogleCodeExporter commented 9 years ago
Thanks for answering.

I've get to the same conclusions about the images it's them :)
My research seems to show that it has to be a bug since the images are 
preloaded before anything else. Just create a quick app widget demo and the 
images will be there, with 5MB of images loaded for a widget that does nothing.

I've opened a bug report 
http://code.google.com/p/android/issues/detail?id=24523 not sure we will get 
answers but well worth trying.

Original comment by Tolriq on 19 Jan 2012 at 12:14

GoogleCodeExporter commented 9 years ago
Bulk update - changing "Fixed" to "Verified" for old bugs.

(Background: I'm changing the "Fixed" status to be considered open, the next 
steps in the lifecycle will be the closed states "FixInTest" and "Verified". 
This lets me mark issues as "Fixed" in commit messages without hiding them from 
the issue tracker.)

Original comment by Klaus.We...@gmail.com on 22 Jan 2013 at 7:33

GoogleCodeExporter commented 9 years ago
Bulk update - changing "Fixed" to "Verified" for old bugs.

Original comment by Klaus.We...@gmail.com on 22 Jan 2013 at 7:34