-
-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OOM with the new sheet approach #275
Comments
Before the png image is 72px, change it to 64px, also can reduce the library size. |
There must be an option to work with Bitmaps. Everyone is doing that. Whatsapp, Slack etc. Maybe there's a magic flag somewhere? |
Some of my users are having OOM too. Signal for Android is using a few methods which might help:
I'll do some tests and see if I can detect a memory saving using profiling tools in Android Studio, but I don't have a low-end device to try them. |
Hi guys! Just noticed this issue. Some years ago, I had same issue dealing with fullscreen backgrounds. They were too much for first price devices. The way we solved it was by using different .png's for different densities. You know: xxhdpi, xhdpi... Devices with low memory tend to be devices with low density, so using it saves so much memory. They started using low density backgrounds, and they had half size than originals, so it saved 75% of memory. Right now, the icons are only inside the nodpi folder. Do you think placing it in different density folders might help to fix OOM error? If so, I could do some Photoshop boring and repetition based tasks 😇 |
It could help but then the library size would go up again which was the entire point of having a single sheet. Also if we scale the images down they might become blurry. Maybe one sheet per category is the way to go. |
Oh, the idea was to scale down images but without compromising final quality, just the needed to fit well on such density. Right now, I guess that emojis have the size to be shown great on our developer high end devices. So, it's a waste of memory when a common user has common low-end device. I also guess (I'm new in the project, I'm always guessing) that one reason to only have the nodpi folder is because a developer can choose to show emojis in a very big size, and that's what you are afraid of when talking about loosing resolution. Well, to fix it, if one app dev chooses to show the icons in a very big size, the library is also able to get emojis from a bigger density folder by using mipmap folders. More thoughts...? |
Oh, I forgot the apk size question! About the size of the library, if you really want to make it SMALL we should put all emojis in a server and download them as soon as possible, using Glide or something like that. Another good think about it is that Glide will resize emojis according to the user screen before showing them, and also using 16 bits instead of 32 for further memory saving. |
Then we're just rebuilding the emoji support from Google. Which we have a module for to leverage that. Glide and downloading could be an option for another module but the main approach should be having the emojis as images. |
Sorry, I don't get why using mipmap folders will be just rebuilding Google's emoji support... You're putting there great icons and also showing the emojis keyboard, so... I think you have only read one of my two comments 😅 |
That's rebuilding the emoji font provider from Google. Previously we didn't get the emojis in a bigger size so we just used nodpi and it worked for everyone. Already now on some high resolution devices they are blurry. |
@vanniktech yesterday I did some experiment with having a half size .png file, and it saves like 50% of memoy... while I expected 75% moreless. But right now, I'm not sure if it will be useful, because there aren't too much devices that can handle that small file without showing blurry emojis. For sure you knew it, but I needed to try 😅 @rubengees one question related to this: do you know if the devices related to the issue have a low-density screen or a high one? Some data to showcase my experience:
|
Regarding increasing APK sizes: the new App Bundle format from Google will create a custom APK for each device downloading from play store containing only the resources for this resolution and ABI. It's not quite mainstream yet since we need Android Studio 3.2 to use it (which is in beta2 right now) but it might make this approach easier to consider. Another approach would be to have per-resolution APK splits, but that is a PITA to set up. |
App bundles will help for sure - yes. Still it would me nice if we wouldn't practically force everyone to use it by having a big library size. |
@rocboronat The device I originally reproduced this with had naturally a low-density screen due to it's age. I think most low-memory devices also have a low-density screen, but I don't know if we can rely on that. I have been thinking about dynamically downsampling the image if not enough memory is available (as recommended in the official guides), but would need testing with various devices to see how bad the images would look on a really low-ram device. |
I can help with testing on low memory devices. |
We are currently considering switching to this library and were concerned about memory consumption. So we did some measurements on a low memory device that you might be interested in: https://code.briarproject.org/briar/briar/merge_requests/857#note_28863 We also noticed that you might not be using a We are currently using the Emoji approach from the Signal app which has one sprite per Emoji category. This helps to reduce the memory footprint for cases where not all categories are needed. Combined with a |
@rubengees sorry for the lack of clarification when I mentioned you... May you share exactly what was the density of the phone? "Low density" is too broad nowadays. It's 2018, so I consider "Low density" a Retina display, hihi... Thanks! :·) |
@rocboronat It was a Samsung Galaxy Trend Lite which has 480x800. I tried to do the downsampling approach based on available memory which did work - no more crashes - but lead to really bad looking images, even on a phone with that low of a density. This is because you can only halve the resolution when downsampling. I will look into other options, but not sure what to do at this point... |
Can we do something in the middle? @rubengees was your testing done with one sheet or sheets per category? |
@vanniktech I can't think of any middle ground currently. Sure - we could fall back to those low density images on devices not having enough memory, but I can imagine there are not few active ones in that category and the images do look really bad. It was with one total sheet. Sheets per category would require some work on the generator involving creating the sheets since our datasource does not provide sheets per category. |
Maybe just the sheet per category does the trick. I'm okay with having a worse experience on low memory / old devices. |
Thanks for creating a fantastic library! I just started working on migrating my app from Signal's emoji code to your library, and I'm really impressed with the well-designed API. I did some memory profiling of my app with versions 0.5.1 and 0.6.0-SNAPSHOT of your library, and the master branch of the app which uses Signal's emoji code. Results are here. It looks like 0.5.1 uses less memory than Signal, but also releases less memory during GC. 0.6.0-SNAPSHOT uses more memory than Signal and doesn't release it on GC. This could be a problem for us when 0.6.0 is released, as we're still targetting Android 4. As well as using a separate sheet per category, Signal uses I guess another possibility might be to mmap the file? |
Yesterday we released an update of our app integrating the emoji-ios:0.6.0-SNAPSHOT version. The features we need are not on the release version yet 😅 We started by deploying to 10% of users, and we get the one OOM crash report. I'm sharing here all the info we have about this crash, hope it will help in some way:
|
I'm aware of the problems with memory in the 0.6.0 development version and won't release 0.6.0 until this is fixed. On the sad side I don't have much time to work on this project though so I'm hoping for external contributions.
We can try that out. First the generator would need to be adapter. Maybe it's worthwhile to generate both approaches. One sheet containing every emoji and then sheets per category. That way we can easily swap them out and see which one performs better. |
I've experimented with a few approaches to this and found a solution that seems to work well. The generator cuts the sprite sheet into strips, one sprite wide. (This was easier to implement than creating a sheet for each category.) The strips are loaded on demand and held by SoftReferences, so they're released when the app's under memory pressure. To avoid constantly loading and releasing strips, the most recently used emoji are cached without keeping the whole strip. Here's my branch. If you think this approach sounds reasonable I'll open a PR: On devices with low-density screens, it's also possible to scale the strips (or sheets) by a factor of 2 when loading them, which reduces the memory overhead without increasing the APK size. However, this increases the CPU cost of loading a strip. This branch includes scaling as a separate commit: |
@akwizgran we're going to launch a version to Google Play with your approach. We're using your |
I was on vacation so sorry for the delay. Please do open a PR with your changes @akwizgran |
Hope you had a nice vacation @vanniktech! :) Do you want the branch that uses scaling or the one that doesn't? Maybe there could be an option for the library user to decide about scaling? |
Can we detect whether scaling is needed or not depending on the device? If so that would be favorable. |
Scaling is enabled if the screen density is less than DENSITY_XHIGH. But there's a CPU cost for scaling, so I'm not sure if it's better for low-end devices to suffer the memory cost of not scaling, or the CPU cost of scaling. Scaling is implemented as a separate commit on top of the other changes, so shall I open a PR for the other changes and then we can evaluate the scaling changes separately? |
Yes that sounds perfect! |
I went with the version without scaling to see if the scaling was needed or not. Please, wait for some data before taking any decision 😄 |
Good news there: we are at 6,1% with 0 crashes. IMHO, move on with the PR of the branch |
I'll close this since I've merged the PR which fixed this. #297 |
Thanks everyone for your awesome help! |
SNAPSHOT
I ran into an OOM with one of my old devices when opening an
Activity
with anEmojiTextView
. This is due to the emojiBitmap
being really large when decoded. I can't really use it in production like that sadly.I tried:
I can't come up with a solution at this point. Maybe someone else has an idea? Otherwise: Should we revert?
The text was updated successfully, but these errors were encountered: