out of memory

Started by
9 comments, last by xytor 13 years, 4 months ago
I'm loading a lot of sprites, and VC++ says it's out of memory after it loads about a gig. I watched on Task Manager, and it said I had about
2 gigs of free physical memory when I got the out of memory exception. Anyone know how to fix this?

Advertisement
How are you allocating the memory for your sprites and how many are you creating? Post your Sprite class and post the code where you "load a lot of sprites".
"When you die, if you get a choice between going to regular heaven or pie heaven, choose pie heaven. It might be a trick, but if it's not, mmmmmmm, boy."
How to Ask Questions the Smart Way.
32-bit OS?
I hope you aren't loading an image per sprite. See if you can load an image just once, and share it between all the sprites that need it.
Basically, the LoadFromFile function fails here:
if (!kickImages[ctr].LoadFromFile(filename)) {

After it fails, I try to allocate 5MB to see if it's a mem issue:
char* bla=new char[5 *1000 * 1000];

That allocation throws an exception even though Task Manager says about 2GB is free.


Here's the code that has the issue:

// sfmltest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <SFML/Graphics.hpp>



sf::Image kickImages[400];
sf::Sprite* kickSprites[400];

int _tmain(int argc, _TCHAR* argv[])
{
// Create the main rendering window
sf::RenderWindow App(sf::VideoMode(1920, 1200, 32), "SFML Graphics");


sf::Color black(0, 0, 0);

// load the kick images
char filename[256];
for (int ctr=0; ctr<400; ctr++)
{
sprintf(filename, "C:\\sfmltest\\kickframes\\kick%04d.png", ctr);
printf("%s\n",filename);
if (!kickImages[ctr].LoadFromFile(filename)) {
char* bla=new char[5 *1000 * 1000];

return EXIT_FAILURE;

}
kickImages[ctr].CreateMaskFromColor(black);

// create the kick sprites
kickSprites[ctr]=new sf::Sprite(kickImages[ctr]);


}


Quote:Original post by CodeMunkie
How are you allocating the memory for your sprites and how many are you creating? Post your Sprite class and post the code where you "load a lot of sprites".


Due to memory fragmentation, it's possible you don't have enough contiguous memory (in your address space) for the next sprite. Depending on your OS and settings, your virtual address space could be only 2 gigabytes in size, total. However, 1 gig just for sprites is excessive. There must be a better way to do what you're doing.
As mentioned above, it is very likely you hit the limits of a 32Bit OS. While you have memory to spare physically, each application can only allocate ~2GB of space without special boot flags for windows to take that to ~3GB. But, you also have to consider that allocations fragment memory, and some commands have overhead. You can end up with free address space but not enough contiguous space to complete a large allocation.

Now, assuming my math is right... you are loading 400x 256x256 images in 32bit color. That's... ~13sec of frames at 30fps. You'd probably be better off with video at that point.
Thanks. BTW, is there a way to tell Windows to defrag its RAM?


Quote:Original post by xytor
Due to memory fragmentation, it's possible you don't have enough contiguous memory (in your address space) for the next sprite. Depending on your OS and settings, your virtual address space could be only 2 gigabytes in size, total. However, 1 gig just for sprites is excessive. There must be a better way to do what you're doing.


The point being here isn't the ram issue, its that you are most likely loading all of your images multiple times. Say if you have 10 sprites in a zombie animation, you can have 1000 zombies on screen and only have those 10 images loaded, just each zombie has a pointer to the frame of animation (0-9).

pseudoish code

#include <map>spriteloadclass{	map<string, image*> Sprites;	image* func_add_sprite(string filename)	{		map<string,image*>::iterator found = Sprites.find(filename);		if(found != Sprites.end())			return (*found).second;		else		{			image* newSprite = loadImage(filename);			if(newSprite == NULL) //ie image didn't load correctly				return NULL;			Sprites.insert(pair<string, image*>(filename, newSprite);			return newSprite;		}	}}


This would load each image only 1 time. (Image is your image datatype, and loadImage is whatever function you are using to load an image (this assumes it returns a pointer to the image it loaded and is NULL if it couldn't load that image)
Quote:
Thanks. BTW, is there a way to tell Windows to defrag its RAM?

This isn't Windows that has fragmented memory. It is your application. Windows provides all applications with a virtual address space. In 32bit windows, this is 4Gb with 2Gb reserved for the system.

This topic is closed to new replies.

Advertisement