Speicherproblem?
-
Hey @all,
ich habe einen TCP Server geschrieben, der Dateinamen empfängt und dann pro datei eine MD5 summe alle 16 KB errechnet.
Mein Problem ist nun das der TCP Server mit 2,134 K gestartet wird.
Nachdem er mit den Dateien fertig ist bleibt er auf 16,175 K stehen. Was kann daran schuld sein das ich nicht mehr auf meine 2,134 K komme?Memory Leaks habe ich keine gefunden "new" wird immer sauber mit "delete" beendet und speicher von maps und listen wird auch immer freigegeben. Was ich nur gemerkt habe ist das er beim "fread" ziemlich stark ansteigt.
Lg _freeze_
-
Ich nehme mal an, das du mit 2,134 K den Speicherverbauch meinst.
Was bitte ist ein "fread" - mal fuer Laien?
Falls du wirklich fuer jedes new ein delete aufrufst (auch fuer jedes new[] ein delete[], hoffe ich!), hast du eventuell Container benutzt, die noch voll in der Ecke stehen, oder irgendwelche Streams deren Buffer nicht geleert sind?
-
fread ist eine C Funktion und Blöcke von einer Datei zu lesen siehe http://www.cplusplus.com/reference/clibrary/cstdio/fread.html
wie ich bereits geschrieben habe leere ich meine container wieder
ja mit 2,134 K bzw. 16,175 K meine ich den Speicherverbrauch im Task-Manager/Process Explorer
Lg _freeze_
-
Kann durchaus sein, daß der Verbrauch harmlos ist - der Heap-Manager nimmt die Speicherbereiche zwar wieder zurück, aber gibt sie nicht sofort ans System weiter, weil du sie ja eventuell noch mal benötigen könntest. Was kommt denn heraus, wenn du mehrere Dateien nacheinander einliest? erhöht sich der Speicherbedarf weiter oder bleibt er bei 16k stehen?
-
Nein er erhöht sich weiter
das ist ja mein Problem. Kann ich nicht irgendwo explizt sagen das er den heap freigeben soll?lg _freeze_
-
freeze schrieb:
Nein er erhöht sich weiter

Hmm, das ist seltsam - vermutlich liegt der Speicher doch nicht im Heap-Manager rum (der würde nämlich als erstes diese Reserven aufbrauchen, bevor er neuen Speicher vom System anfordert). Btw, wie groß ist eigentlich die Datei, die du da einliest?
das ist ja mein Problem. Kann ich nicht irgendwo explizt sagen das er den heap freigeben soll?
Nicht portabel - offiziell kannst du den Heap-Manager nur über new/delete bzw. malloc/free erreichen, was er sonst noch kann, liegt im Ermessen des Compiler-Herstellers.
PS: Einen Versuch wäre es auch wert, von FILE* umzusteigen auf fstream.
-
Also Die Dateien sind später max 30 GB+ groß. auf FILE* mit ich deswegen um gestiegen da ich mit fstream kein unsigned char* einlesen kann. deswegen die alternative zu FILE*. Ausserdem ist es auf einiges schneller als fstream. Zumindest kommt es mir so vor.
Bei dem Projekt habe ich ca. 24 h Zeit um die md5 bzw. SHA-1 summen für ca. 500 Dateien zu berechnen und den unterschied zu transferieren. Das die Dateien einer Datenbank gehören wollte/muss ich mit dem Speicherbereich so gering wie möglich sein, und die Dateien so schnell als möglich lesen können, da nach den 24 h ein DAtenbank interner Prozess läuft der sofort schreit wenn jemand auf seinen Dateien herumfummelt.
Lg _freeze_
-
Schließt du die beteiligten Dateien auch wieder, wenn du sie komplett eingelesen hast? (fclose())
-
ja mache ich....
Hier mal der Source
std::string getSHA1Sum(FILE* file, unsigned int bytes) { SHA1* sha1 = new SHA1(); int length = 0; // unsigned char* digest = NULL; char *buffer = new char[bytes]; memset(buffer, 0, bytes);//1024); length = (int)fread(buffer, 1, bytes, file); sha1->addBytes(buffer, length); std::string src_sha1_hex = sha1->toHex(); delete sha1; delete [] buffer; return src_sha1_hex; } std::string getMD5Sum(FILE* file, unsigned int bytes) { MD5 *md5 = new MD5(); int length = 0; unsigned char *buffer = new unsigned char[bytes]; memset(buffer, 0, bytes);//1024); length = (int)fread(buffer, 1, bytes, file); md5->Update(buffer, length); md5->Finalize(); std::string src_md5_hex = PrintMD5(md5->Digest()); delete md5; delete [] buffer; return src_md5_hex; } void createHashFile(std::string source_file, std::string target_file, unsigned int bytes, std::string hash_algo) { FILE *src_file = NULL; src_file = fopen (source_file.c_str(), "rb"); unsigned int source_size = getFileSize(source_file); int count = 0; //unsigned int failed = 0; #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__TOS_WIN__) transform(hash_algo.begin(), hash_algo.end(), hash_algo.begin(), toupper); #elif defined(linux) || defined(__linux) transform(hash_algo.begin(), hash_algo.end(), hash_algo.begin(), (int(*)(int))std::toupper); #endif if(hash_algo == "SHA1") hash_algo = "SHA-1"; // Write the header to the hash file fstream file(target_file.c_str(), ios::out); file << source_file << "\t" << bytes << "\t" << hash_algo << "\t" << std::setw(15) << std::setfill('0') << source_size << endl; if(src_file != NULL) { unsigned int file_pos = 0; for(;;) { if(file_pos >= source_size) break; unsigned int bytes_to_read = bytes; if((file_pos + bytes_to_read) > source_size) bytes_to_read = source_size - file_pos; std::string checksum = ""; if(hash_algo == "SHA-1") checksum = getSHA1Sum(src_file, bytes_to_read); else if(hash_algo == "MD5") checksum = getMD5Sum(src_file, bytes_to_read); file << std::setw(15) << std::setfill('0') << file_pos << "\t"; file << std::setw(15) << std::setfill('0') << (file_pos + bytes_to_read) << "\t"; // file << std::setw(15) << std::setfill('0') << source_size << "|"; file << checksum << endl; file_pos += bytes_to_read; count++; } fclose (src_file); file.close(); } }der Aufruf würde dann wie folgt aussehen:
createHashFile("test.dat", "test.dat.hash", 16384);Also er liest immer 16 KB von test.dat und schreibt dann folgendes in die datei "test.dat.hash"
Als Beispiel ist es eine 500 MB Datei zu Testen:000000000000000 000000000016384 97c658942c7e293bbf910734f398c3074433aa53 000000000016384 000000000032768 05ef3bdf8678a282a9550b22f4744194ecf07914 000000000032768 000000000049152 3934b9ed6c4f1b0f2399941d213b5a3c363ab620 000000000049152 000000000065536 302f5d85f88c7603f1070c07b9be24e39ed6d5b7 000000000065536 000000000081920 f55b5719a8196d645fbb6177b702a1d584412107 000000000081920 000000000098304 3e79997ddaaa73adcbb44580dd000f8026b226d6 000000000098304 000000000114688 847115831c4eb01a10e012a530e2fdce2910dd9a 000000000114688 000000000131072 3e17159763fca75cc10dd7757647641e9105b5e1 000000000131072 000000000147456 820cef420a363d694d1a62fd6fae603f932b6204 000000000147456 000000000163840 ae09d0cd2c9686e8b5bdd4c35e29e4c16e527f40 000000000163840 000000000180224 8ef0207df163f58e0d740e6c7230e857c7fec4f9 000000000180224 000000000196608 d89dc7188375e5d2f8cc76807a52629ffed2022b 000000000196608 000000000212992 d62b88adf7a500df9982285dad7ffb6ad7a3d7e9 000000000212992 000000000229376 892bfff87d9438890f0a7562edb3cc73eddfa21e 000000000229376 000000000245760 b0b20a7bcc1ac4b09246957bb0de0f6ce58d0d45 000000000245760 000000000262144 40afe783d42e354e8b4910d09856ff580979813d 000000000262144 000000000278528 395fa2dc7b8e6a6e5b9207c66936f21093cb3a87 000000000278528 000000000294912 e62b1d57dc1ed6be63e12b995c19d219864672bf 000000000294912 000000000311296 9b6390da47b5de1f5f96b664b88a6d18c322ff86 000000000311296 000000000327680 f062178f5d769b128000c37315d2dfa3fe66cd47 . . . 000000586989568 000000587005952 a3edb12ccd34a27cad16862cf6e24b1dff2e9967 000000587005952 000000587022336 d9e03c528ab743a7a47dbec5ba0a25f73d524f59 000000587022336 000000587038720 31caccd86e787e0db05887661a04cf387844de00 000000587038720 000000587055104 730db1f4052ebb1f09801f4bbc6755e30f63a228 000000587055104 000000587071488 d280f9524a2373b8c88575bf4237bd13b80a3025 000000587071488 000000587087872 0aa8bf17b9ddfe3253464cb73c107570b227953e 000000587087872 000000587104256 7fb1dbf9234a01c1124f8c99312325e2a8a41391 000000587104256 000000587120640 c4b4956755c4527cf6125c63de67d040ca8211cd 000000587120640 000000587137024 8397c0b6d12183471000d9dc3155e51d2e97a603 000000587137024 000000587153408 39150e4c05d3091f1fdeb789c66a09ba408075ff 000000587153408 000000587169792 ad4cee7457c7646f0773d8cab0b95248185647b8 000000587169792 000000587186176 fefb4523600f9508f6ea299e0f04a357e28cf5ac 000000587186176 000000587202560 d72d6897ef569b694e7b3dbfd7e2907042b2acfd 000000587202560 000000587210752 85307fb0d827c4d1ad3a497dc5a2b991d8f49916Lg _freeze_