[kstars-devel] analysis of memory consumption
Heiko Evermann
Heiko.Evermann at gmx.de
Sun Aug 31 01:00:55 CEST 2003
Hi everyone,
I have analyzed the memory behavior of kstars:
Our observation from the process stats is that we need about 500 bytes
per star
when we force loading of all stars.
How big are the objects that we are dealing with?
This can be found out by using sizeof:
bool KStarsData::readStarData( void ) {
kdDebug() << "size of QString " << sizeof (QString);
kdDebug() << "size of Star Object " << sizeof (StarObject);
kdDebug() << "size of dms " << sizeof (dms);
kdDebug() << "size of QStringList " << sizeof (QStringList);
kdDebug() << "size of double " << sizeof (double);
kdDebug() << "size of bool " << sizeof (bool);
kdDebug() << "size of SkyPoint " << sizeof (SkyPoint);
kdDebug() << "size of SkyObject " << sizeof (SkyObject);
The (commented) result is this:
double:
size=8 bytes
bool:
size=1 byte
QString:
size=4 bytes (for empty string, plus dynamically allocated content,
which might be shared??)
QStringList
size = 4 bytes (for empty list, plus dynamically allocated content)
dms:
size=36 bytes (via sizeof)
details:
double D = 8 bytes
mutable double Radians = 8 bytes
mutable double Sin = 8 bytes
mutable double Cos = 8 bytes
mutable bool scDirty = 1 byte
mutable bool rDirty = 1 byte
sum: 34 bytes
2 bytes not accounted for. Rest might be padding to get a multiple of a
dword as size
SkyPoint:
size=292 Bytes (via sizeof)
dms RA0 = 36 bytes
dms Dec0 = 36 bytes
dms RA = 36 bytes
dms Dec = 36 bytes
dms Alt = 36 bytes
dms Az = 36 bytes
dms galLat = 36 bytes
dms galLong = 36 bytes
sum: 8*36 bytes = 288
plus 4 bytes for the pointer to vtable
all bytes accounted for
SkyObject
size=332 bytes (via sizeof)
is a SkyPoint => 292 bytes, vtable pointer already included
unsigned char Type 1 byte
float Magnitude 4 bytes
QString Name 4 bytes (+ variable content)
QString Name2 4 bytes (+ variable content)
QString LongName 4 bytes (+ variable content)
QStringList ImageList 4 bytes
QStringList ImageTitle 4 bytes
QStringList InfoList 4 bytes
QStringList InfoTitle 4 bytes
QString userLog 4 bytes
sum: 329 bytes accounted for. rest might be padding to get a multiple of
dword as object size (compiler dependent?)
StarObject
size=364 bytes (via sizeof)
is a skyObject => 332 bytes
QString SpType => 4 bytes
double PM_RA 8 bytes
double PM_Dec 8 bytes
double Parallax 8 bytes
bool Multiplicity 1 byte
bool Variability 1 byte
sum: 362
2 bytes not accounted for, maybe padding to get a multiple of a dword as
size
This means that about 140 bytes are not accounted for. I am not sure
whether they can
be completely explained by string lengths of names. The names of most
stars should be
much simpler.
A big byte consumer is dms, which is used several times. I know little
to nothing about
our algorithms. To me it makes sense to keep the catalog coordinates in
double precision.
However I am not so sure whether RA and Dec in skypoint (current true
sky coordinates)
need to be kept in double precision. I suppose that they are mainly used
for projection
to a 2d screen and are not used as a base for further calculations.
Could it be enough
to keep them in float precision by having two dms classes: one in double
and one in float
precision? This might save 36 bytes per star, which is about 10% of the
memory load.
And from a
The two dirty flags (2 bits) make up for a total dword in memory
consumption. This
is unfortunate. But I see no easy way to get around this. One could set
the sin/cos to
illegal values (like >1), but then checking for dirty would result in a
floating point operation,
which is too expensive. Perhaps somebody else has an idea? We have 8 dms
objects in a
StarObject. Each of wich spends 4 bytes on dirty flags, which is 32
bytes of memory,
or (again) about 10% of the memory load. Do all dms objects get invalid
at the same time?
Or do some (like the catalog coordinates) never get outdated?
Do we need to keep D and radians in a dms object? Could the algorithms
be rewritten so that
we only ned one of them (without losing optimizations that we like a lot?)
When I follow where data comes from, then I am tempted to say that the
dms object is
an expensive way of storing a double value (36 bytes instead of 8). It
is quite a price to
pay for optimization. Do we need sin/cos from all these values so
frequently that we
have to precompute them all? Just imagine that 8 bytes were enough: this
would save
8*28 bytes per star, or 224 bytes, which is half the memory load of kstars.
I think most star objects will only have one name? So we might introduce
a class of its
own for them? (saves 8 bytes for 2 QStrings, plus the string content,
just in case
QString does not recognize that one contains the same value as the other?)
The whole area of QString memory management might be worth
investigating. Maybe it is
not as good as I think?
And all this still leaves some bytes unaccounted for. Are there any
memory leaks in the
reading of the stars from disk? Files that are not closed etc? Has
anybody checked for
leaks recently?
By the way: set both faint limits (zoomed in and out) to 1. Close and
restart kstars.
Go into settings, set limit to 8. The missing data does not get loaded
in the current cvs...
So much for tonight.
Any comments, ideas etc?
Greetings from Hamburg,
Heiko
More information about the Kstars-devel
mailing list