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	85307fb0d827c4d1ad3a497dc5a2b991d8f49916
    

    Lg _freeze_


Anmelden zum Antworten