AAssetManager_open trigger filemap: Out of memory on 32bit devices

307 views
Skip to first unread message

seal2002

unread,
Aug 27, 2021, 12:43:17 PM8/27/21
to android-ndk
Hello,

I have an issue with use AAssetManager_open to open the file on my game.
After open some of pack, it started to trigger the error and warning

08-27 23:28:58.316 14778 14975 E filemap : mmap(0,251402641) failed: Out of memory 08-27 23:28:58.316 14778 14975 W asset : create map from entry failed

And my game cannot read data any more - app crash

It happens on device 32bit with FW 7.1.2. After we change from GEF to Play Asset Delivery.

My game has around 10 packs, some of them is large but not excess 300MB.

This message happens after app read  4 packs successful.

I'm not sure it is common issue for all device 32bit or only happens with FW 7.1.2.

Do you have any idea about it?

Thanks

John Dallman

unread,
Aug 27, 2021, 4:07:27 PM8/27/21
to andro...@googlegroups.com
I don't have any specific knowledge of these APIs, but there is an obvious possibility. Are you closing the files you have opened, or leaving them all open? If you are leaving them open, they're apparently taking up address space, and it's very possible to run out of that in a 32-bit process. 

If you are leaving them open, try closing them and see if it makes a difference. 

Best,

John

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/1666a61c-a2e4-4373-b43f-96762038672dn%40googlegroups.com.

seal2002

unread,
Aug 30, 2021, 1:44:34 AM8/30/21
to android-ndk
Thanks John, I leave them open. As the game, open and read data on the pack, push to GPU, not close them after all. As the game tech design from begining, our team make the engine like it.
And we use GEF, everything is okay, even the code behind is use mmap as well. So that why I have the question, AAssetManager_open should use the same mmap too (I guess from the error log) but why It crash?

Thanks

John Dallman

unread,
Aug 31, 2021, 6:20:14 AM8/31/21
to andro...@googlegroups.com
I don't think it's crashing, as such. I think your program is running out of address space, and that problem is causing the mmap() call to fail. 

I suggest that, as an experiment, you should try closing the files to see if the problem goes away. If it does, that is evidence that running out of address space is the problem, and then you know what to look for. 

John

seal2002

unread,
Aug 31, 2021, 10:15:14 AM8/31/21
to android-ndk
Yes, I text wrong the text above  :(.  Why it crash should be Why it is throw the out of memory).
I tried to switch huge packs - (200MB - 500MB) /pack(which store all resource files) x 8 to asset  invidual  file and the issue has delay. It will be failed when the game reach to out of address space.
And thank for the suggestion, so I should try to close each file after open it. Do you have suggestion how to debug the address space on the android?

Thanks

John Dallman

unread,
Sep 6, 2021, 5:14:50 AM9/6/21
to andro...@googlegroups.com
The first step in debugging this is to print the size of each chunk of address space as you map it and free it, and keep a running total of the amount allocated. After that, I don't know: I've never used this style of loading on any operating system. 

John

seal2002

unread,
Sep 27, 2021, 2:54:04 AM9/27/21
to android-ndk
Thank you for your suggestion. Currently I leave the issue as open - because it is small of devices has that trouble... And no free time to debug deeper on it.

seal2002

unread,
Oct 4, 2021, 3:09:46 AM10/4/21
to android-ndk
Hi, could you please let me know the function should I use to log the address space?
currently I try with getrlimit(RLIMIT_AS, &rlim); but it is same value for cur and max and the valuable is not reallity `4294967295`
size_t pagesize = getpagesize(); pagesize = 4096

John Dallman

unread,
Oct 4, 2021, 8:00:41 AM10/4/21
to andro...@googlegroups.com
I'm sorry, but I don't understand what you are asking. The question and the code don't seem to be related. 

John

seal2002

unread,
Oct 4, 2021, 10:18:36 AM10/4/21
to android-ndk
Sorry to make you confuse, let me sumup why I do it.

The first step in debugging this is to print the size of each chunk of address space as you map it and free it, and keep a running total of the amount allocated

I thought that I need to print the address space is using by the process. As out process is using  AAssetManager_open, so I look at the https://developer.android.com/ndk/reference/group/asset to find the function to get total amount of address space used but no luck.

So I search around to google, and find the function getrlimit at https://man7.org/linux/man-pages/man2/setrlimit.2.html

RLIMIT_AS This is the maximum size of the process's virtual memory (address space). The limit is specified in bytes, and is rounded down to the system page size. This limit affects calls to brk(2), mmap(2), and mremap(2), which fail with the error ENOMEM upon exceeding this limit. In addition, automatic stack expansion fails (and generates a SIGSEGV that kills the process if no alternate stack has been made available via sigaltstack(2)). Since the value is a long, on machines with a 32-bit long either this limit is at most 2 GiB, or this resource is unlimited.

then I print the value to see the number of limit, but no luck...

I have try with dumpsys - https://developer.android.com/studio/command-line/dumpsys#meminfo and face 2 issues
1/ The game crash so fast, thinking to sleep the process than manual call dumpsys
2/ Still Not understand the value of so.mmap ... total value of it does not equal private & dirty...

Thanks,

John Dallman

unread,
Oct 4, 2021, 11:20:31 AM10/4/21
to andro...@googlegroups.com
The simpler way is to record the size of each mmap area as they are created, by adding some reporting code to your existing code that loads the assets. 

John



seal2002

unread,
Nov 18, 2021, 2:23:20 AM11/18/21
to android-ndk
Hi again,

I'm not sure I'm understood your idea, I use the code 
https://developer.android.com/ndk/reference/group/asset#aasset_getlength to print the total size use of each mmap? is it right? or we use another function to do that?

Thanks

John Dallman

unread,
Nov 23, 2021, 4:40:55 AM11/23/21
to andro...@googlegroups.com
I don't know. As I said at the start, I have no specific knowledge of these APIs. If you add up the asset sizes, what is the total? 

John

seal2002

unread,
Nov 26, 2021, 4:56:30 AM11/26/21
to android-ndk
Hi,
It is around ~ 1GB, ~1073000000 Byte.

John Dallman

unread,
Nov 29, 2021, 2:07:23 PM11/29/21
to andro...@googlegroups.com
1GB is quite a large chunk out of a 32-bit app's address space. What else is taking up memory? 

John

seal2002

unread,
Dec 3, 2021, 4:53:27 AM12/3/21
to android-ndk
Hi,

First, I'm very appreciated with your input.

To be honest, I don't know how to log the mmap used correctly. Currently I call adb from my PC to log the mem - it might not exactly because has some delay... I try to call those command from my game but it doesn't effect.

I attached 2 log of them.
1. Mem.log: use `adb shell "cat /proc/meminfo"`
2. MemLogByPMap.log: adb shell pmap -x ProcessID

Thanks,
MemLogByPmapCommand.log
Mem.log

John Dallman

unread,
Dec 3, 2021, 5:44:16 AM12/3/21
to andro...@googlegroups.com
Aha. mem.log makes the answer clear:

MemTotal:        1547544 kB   # About 1.5GB on this device. 
MemFree:          661772 kB   # Android is using about 0.6GB
MemAvailable:     824008 kB   # You have only about 0.8GB free

I'm surprised that you are managing to mmap your 1GB of resources. You won't have any significant space left for anything else. Your choices are to stop taking up so much space with mmap'ed resources, or to only run devices with more memory. 

John

seal2002

unread,
Dec 3, 2021, 5:50:45 AM12/3/21
to android-ndk
I'm blind with those information .... :(. Very clear now. Thank you, John.
Reply all
Reply to author
Forward
0 new messages