Does more instructions in a program use more RAM than programs with few instructions?

Started by
22 comments, last by Nicholas Kong 10 years, 2 months ago

It is not always the case that the entire program code is loaded into memory


Oh really? Why is this so?

Because the OS has the ability to do memory mapping.
http://en.wikipedia.org/wiki/Memory-mapped_file
This way it can intelligently load the parts that are actually used, while setting aside the memory addresses for the whole thing if needed.


It can also happen completely independent of the OS.

For example, Final Fantasy 7 (Playstation version) has code broken up into several modules (menu module, battle module, etc.), and at any given time only the relevant modules are loaded in RAM (i.e. the menu module is loaded when the player opens the menu, and immediately unloaded when the player closes it). The only module that is always loaded is the one that is responsible for loading other modules and booting the game.
Advertisement

Memory mapped files are a feature that has to be explicitly coded to use. So it works however the programmer write it to work.

For automatic swapping between harddisk and memory, a swap/page file is used, which depending on the OS can be a special file or a hard drive partition. Yes, all Operating Systems have paging, modern and not so modern. It isn't aware of what "map" the player is on, but it tries to swap out the least recently accessed memory first, with some intelligence to achieve application fairness. With modern physical memory sizes, paging isn't called for as much, although the same infrastructure is used to initially load application memory.

While memory mapped files are handled entirely in code, swapping between hard disk and memory is done with support from the CPU itself. If you try to access part of memory that is paged to disk, the CPU will 'throw' an exception, telling the operating system that the piece of code needs to be moved back into RAM before execution can continue. Exceptions in a CPU are thrown whenever certain 'bad' situations arise, like for instance division by zero. In user space, these exceptions are recoverable, meaning that the operating system terminates the program and tells you that the program did something wrong. If this happens in a core system driver, or in the operating system itself, you will get what is the equivalent of the blue screen of death on Windows, depending on the operating system.

Edit: I wrote that exception are thrown in 'bad' situation in quotes, because not all exceptions are bad. Hardware interrupts, for instance behave very much like exceptions, but are just signals to tell the operating system to handle 'urgent' situations. In either case, the processor immediately stops what it was doing to handle the situation before it returns to continue where it left off before the interrupt/exception.

You can use the JarFile class to open your own file, search through the file listings for the right JarEntry, and then open it as an input stream decompressing it as you stream the data out the same way any .zip decompression library works. For some resources this can happen automatically. No need to decode the file out to disk unless you have some disk-based need.

It turns out the JarEntry is another Java class built in to the Java Standard Library. So with the above mentioned Java classes, the jar will just read the files embedded in the jar exe?

One thing I should mentioned is that I am using FileInputStream. Here is my Java game code for reading the art assets.

image = ImageIO.read(new FileInputStream(new File(animations[i])));
Does the above code being FileInputStream have any effect on when my java jar exe not running when I double click on it (unless I extracted the folder from the jar exe)?
Again, a jar file is just a compressed archive file.

When you are running it (by clicking on it or debugging it or any other method) the operating system usually locks the file so it cannot be modified, but you absolutely can read from the file all you want. When the OS locks a file like that other processes can still read from it assuming they have permissions.


Java provides multiple ways to read data from an archive. All of them use a stream-based readers because the archive format uses stream-based compression.

Probably the most commonly used is Class.getResourceAsStream(filename); which finds your file inside the archive and returns your stream directly from the archive. You will need to properly name your file to account for the way Java handles paths inside a jar, perhaps "/com/myname/image.jpg", but it should work just fine. You could provide that stream to your ImageIO.read() function and it would stream just like any other input stream. No need to make a second copy of the data to a temporary file.

For a little more complex functionality you can create a JarFile object passing in your jar file name, loop over all the JarEntry items (those represent the individual file streams) and when you find the one you want, run the line: InputStream input = myJarFile.GetInputStream(myJarEntry); Like the example above, it returns your stream directly from the archive. It is more flexible because you aren't limited to your own file, you can put a different file in as the target for JarFile assuming you have appropriate permissions. Also because you can enumerate over all the different file streams you aren't required to know the exact file name in advance. But if you do know the file name and it is part of your own archive, the result is functionally identical to the Class.getResourceAsStream() version, giving you a stream within your own archive.

You can also open the file as a zip archive, find the entry using exactly the same process as the JarFile/JarEntry search, and end up with a stream.

Or open the file as a regular binary file and process it yourself, the file format is well-documented. This method also works at finding files that don't show up on the archive's manifest, since it is possible to include unnamed file streams and not include them in the listing, or to mark a file as deleted by appending a new listing that doesn't include the removed file. In both cases the data is still present, it just doesnt show up directly by name.

There are lots of options.


Probably the most commonly used is Class.getResourceAsStream(filename); which finds your file inside the archive and returns your stream directly from the archive. You will need to properly name your file to account for the way Java handles paths inside a jar, perhaps "/com/myname/image.jpg", but it should work just fine. You could provide that stream to your ImageIO.read() function and it would stream just like any other input stream. No need to make a second copy of the data to a temporary file.

I will see if I can get this part to work. It definitely seems to be the easier way to do it concept-wise. Thanks Frob!

This topic is closed to new replies.

Advertisement