3

I'm working with an open-source .NET app that takes a long time to startup and initialize. Its creating thousands of objects and configuring them for first time use. I'm trying to improve this startup time.

Is there a way to capture application memory using the Windows API or similar, and then quickly "restore" this state later after restarting the PC? Essentially is there a way to access and save the underlying memory of a .NET app and have the CLR "absorb" this memory at a later time?

  • The easiest way would be using Windows Hibernate to create "hiberfile.sys", and then saving a copy of this file (if that is possible). Everytime windows starts up, you overwrite the existing hiberfile with the saved "clean" version, for the next startup. This ensures that you can save / restore application state without having to deal with memory, pointers and handles. Could this work?

  • One way would be creating a mem-disk, although I don't know if restoration is possible. (virtual memory that actually works off the HDD, allowing the memory to be saved/restored as a simple file)

  • Similar to this question, but a bit different since I don't mind re-inserting the application memory at the exact address it was saved in. The PC is entirely in my hands, and for the sake of simplicity assume there are no other apps running.

  • C# does not support continuation out-of-the-box, although the Workflow Foundation in .NET 3.0 and higher allows for workflows to be stopped and restarted. I wonder how an application can behave as a workflow.

  • Raymond Chen argues against this in a blog post, but not much technical data here either.

  • YAPM, an open-source process monitor is able to "display/release/change protection/decommit the memory regions in the virtual memory space of a process". Could this be something similar to what I'm after?

Community
  • 1
  • 1
Robin Rodricks
  • 110,798
  • 141
  • 398
  • 607
  • 1
    I think the best you can do is binary serialization and deserialization – Sergey Rybalkin Mar 30 '12 at 14:40
  • Raymond Chen's article does give technical data, including a few very important examples (the rest of the system does not hibernate, potentially making all external handles and resources invalid). – ssube Mar 30 '12 at 14:55

1 Answers1

3

If you want an unchanged save/load process to avoid first-use, you may look into serialization.

Actually saving the memory could be possible, but you'll run into addressing problems when you try to restore it, and there's a chance you may not have enough memory, may not have a free block in the same size, or so on.

Serialization at an object level, or even a large group of objects, will allow you to save them and their state in an almost-identical manner to dumping memory, but greatly simplify the loading process and make it far more reliable. .Net offers pretty good serialization support, and can output to binary files (small but version-dependent) or XML (larger, human-readable, somewhat more flexible). Other libraries may offer more methods of varying use (I believe there is a JSON one, which is slightly more verbose yet, but works with web apps).

Depending on how your app works, you may want to/be able to create the first-use models on the first run, serialize them to disk, and load them from then on. With some work, it should also be possible to add all the objects (of varying types) to a single collection and serialize that, allowing all the data to be stored in one file.

So yes, this is possible and may indeed be faster, although not how you originally thought.

ssube
  • 47,010
  • 7
  • 103
  • 140
  • What if the memory was re-inserted at the exact address it was lifted off at? Something like Windows Hibernation / restore? The entire PC is in my control. – Robin Rodricks Mar 30 '12 at 14:45
  • It's very difficult, if not impossible, to guarantee that. Hibernate works on a kernel level, so unless you can force the kernel to never allocate any memory within that block, load the stored data, and then map it to a specific address in the process' virtual memory map, it's not going to happen. Most or all of that isn't possible in .Net, and probably not even C/asm working directly with the WinAPI. Serialization is definitely a more correct approach, within the .Net world, and may save a lot of headache later (simpler and safer). – ssube Mar 30 '12 at 14:49
  • 1
    There's a slim chance, but the only way to create a hibernation file is to trigger a hibernate, so it would take a bootloader running before the Windows one to make a copy of and then swap out the hibernation file for use. Screwing around with the kernel's boot process is **not** a good way to solve serialization. – ssube Mar 30 '12 at 15:14
  • Not too hard. Suppose we boot into GRUB or something that could trigger such code. `hiberfile.sys` is inaccessible once you've started windows? I was suggesting copying over the backup for the NEXT restart, so an app running in windows could do it. Is this possible? – Robin Rodricks Mar 30 '12 at 15:18