2

I'm trying to embed binary media resources into source code. I will going to use plain C-array (char[]) to store binary. (with something like this: Embedding binary blobs using gcc mingw) Because managing media files resource separately is very annoying work because the symbol it is hard to determined at compile time, and makes my customers annoying too.

Anyway what I'm concerning is memory consuming. If I store a PNG image, actually, I don't need the persistent binary anymore after I loaded live image instance (UIImage*) from it. But I think the persistent binary will remain in memory because

  1. it's part of code
  2. and it's constant.

I don't know any option to remove it from memory.

How can I let a C-array always to be accessed from disk directly instead of remaining in memory?

PS. I can limit my build and execution environment strictly. I will use Clang and the program will be run on iOS. Anyway I don't mind to use any of extra build tool :)

Community
  • 1
  • 1
eonil
  • 83,476
  • 81
  • 317
  • 516
  • If you want to fall back to loading the image from disk via C-array, why not just just load the PNG from disk? Not getting the difference ... – bryanmac Feb 02 '12 at 01:21
  • @bryanmac Ah I'm sorry for my unclear question. Anyway I'm not trying to load a file via C-array. I added a link to a QA which describing the method what I'm trying. – eonil Feb 02 '12 at 01:35
  • 1
    Note that on most virtual memory systems, even though the data uses address space, it won't be paged into actual physical memory unless you actually use it (though I'm not familiar enough with IOS to know if that statement is true there). This might not really be a problem you need to solve. – Michael Burr Feb 02 '12 at 01:39
  • @MichaelBurr Oh I wish and believe it. Now I just want to know there's more explicit way. Thanks :) – eonil Feb 02 '12 at 01:44
  • 1
    @Eonil: there is, see my comment on `madvise` – mvds Feb 02 '12 at 01:46
  • I'm not quite sure I understand your question but, if I understand correctly, you want to use a char[] to load a PNG into a UIImage? Like, in your source code, you would have the binary data laid out right there? – Simon Germain Feb 02 '12 at 01:22
  • Yes, yes. That's what I want. I will write each bytes in my source code. Sorry again for my unclear question :) – eonil Feb 02 '12 at 01:40
  • Sounds like you'd be better off saving the PNG in your project and read it from the disk with [UIImage imageNamed:@"image.png"]; – Simon Germain Feb 02 '12 at 03:14

4 Answers4

4

I don't fully understand what you are saying or trying to solve, but it sounds like you are looking for memory mapping. See man mmap.

ps reading again, if I understand your question correctly, you want to make a fat binary containing all resource data. In that case, the OS will probably page out unused parts of it, so the memory is "freed" automatically. ("freed" in the sense of releasing physical memory that can be used for other purposes) So the persistant binary will remain in virtual memory, but not in physical memory.

update to explain a little further

On your Mac, in the terminal, run

$ vmmap -resident $$

This will show the virtual memory mapping for your shell, showing total memory and resident memory. You will see this line:

==== Non-writable regions for process 7139
__TEXT 0100000000-00100099000 [  612K   460K] r-x/rwx SM=COW  /bin/bash

This says, that in this region of memory the file /bin/bash is to be found (memory mapped, again, see man mmap) and that it is not fully paged in; only 460kb of the binary is actually present in memory. Which is interesting because this is the binary actually running. The other lines are interesting as well, but beyond the scope of this question.

so if the OS of choice (iOS) has sane memory management, your problem does not really exist. Just don't touch memory you don't need to use; every time you touch it, the pages are read in memory.

mvds
  • 45,755
  • 8
  • 102
  • 111
  • Oh thanks. That's exactly what I wanted. I think OS will try to do that, but it's not sure because OS don't have information the binary chunk must be freed (i mean physically). Can I mark or code let the OS always do that for specific memory address? – eonil Feb 02 '12 at 01:38
  • 1
    First of all, you could use `mincore` to peek which pages are resident or not. Note that pages are paged in per page, i.e. in blocks of 4 or 8kb. Using `madvise` you can tell the system you will need a page, or that you will not need a page anymore. Telling the system upfront what pages to load can give a performance boost; if you would access some `data[i]` and the page is not resident, your program will *just block as if you had issued a blocking read() call*. This scenario is normally not likely, but in your case... – mvds Feb 02 '12 at 01:45
0

By storing them as resource files on disk instead of as source files. You can't have it both ways.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
0

If you were able to load a shared library you could load an unload the shared library, (for C-arrays) but you can't since it's iOS which is all about the static libraries. Unfortunately, I don't think there's a solution like you want on that platform.

ldav1s
  • 15,885
  • 2
  • 53
  • 56
0

With a UIImage, you may be able to accomplish this -- I've never tried it. What you would need to do is create the UIImage with a CGImage which provides a custom CGDataProvider which used file read or mmap to access data. Not sure it would work -- the UIImage may make a copy along the way for one reason or another, and you've no control over that implementation detail.

You don't want the image in your binary if you also want to free it from memory. Creating a UIImage from a resource in binary could double your memory requirements.

It's hard to tell what you're trying to accomplish, but I sense UIImage's default behavior with bundled images would seem the ideal for your needs as-is…

justin
  • 104,054
  • 14
  • 179
  • 226