I think that's a red herring, and static stuff wouldn't be duplicated in practice.

Let's break this down by chopping memory into roughly three bins:

a) File-backed pages from executables, libraries (i.e. typically shared)

b) Non-shared essential memory - the state of the application

c) Non-shared discardable memory - state which can be recomputed if necessary, e.g. caches, frame buffers etc.

What's the actual upshot difference between the OS doing the serialization (in the form of bulk paging, as opposed to on-demand paging), and asking applications to do it?

Memory written out:

* OS wants to write out (b) and (c), because it's tricky to express your discardable preferences in memory allocations - not only are the pages discardable, but references into the pages need to be zeroed out. (A GC would help a lot here.)

* App can write out (b), but it needs to work quite hard to get there. Likely it will write out a fraction of (b) but do a lot of execution on loading; there may also be bugs or design flaws which lead to less than perfect resumption.

Upshot: There should be little to no difference in random access for writing: both should be sequential writes; but less written for the App model. But the OS model has a different advantage: it can lazily be writing out less frequently written pages to disk, so come suspend time, it has less work to do.

Memory read in:

* OS will read in (a), (b) and (assuming we don't have that GC etc.) (c). (a) will be random reads, while (b) and (c) will be a bulk sequential read.

* App will read in (a) and (b). (a) will be random reads, while (b) should be a bulk sequential read.

Upshot: There should be little to no difference in random reads, while the App should have a little less sequential reading.

So as regards to FS access, I don't see necessarily significant differences in between these two models.

A different matter is resources. Things like sockets, open files, events - or god forbid, system-wide synchronization primitives, etc. Some form of managed memory with opaque handles that understand serialization events would help out in the OS front here. But it shouldn't be intractable; Smalltalk systems and the like have been working with persistent images for a long time.

I actually think a bigger problem is the dynamically available persistent storage space. Having a device that's supposed to have 8GB or 16GB of memory but finding it only has 6.5 or 13 or so, owing to GiB/etc., formatting and OS installation, is galling enough. But having potential 6x chunks of 0.1 or 0.25 going missing has got to hurt. Compression may help; but it's independent of strategy.

What I do think is that an OS and cooperative runtime / GC would do a lot better job of this in terms of user experience than the app writer, who has to balance this requirement with getting all the rest of their app right. The easiest way to do it for the app writer is something along the lines of a save game or a saved document - i.e. persist relevant state, but go through the normal loading cycle at startup before restoring state. Thing is, reinitializing everything is dog slow - many apps take too long to start up, no matter what platform they're running on, desktop or phone.