Frage bezüglich Speicher beim Laden eines Bildes
-
Hio,
ich habe folgenden Funktion in einer DLL drin, welche ich über Java aufrufe:
JNIEXPORT void JNICALL Java_MainClass_NewJFrame_paint(JNIEnv *env, jobject obj, jint handle, jint x, jint y, jdouble scale,jstring str) { HWND hWnd = (HWND)handle; const char *c_string = (*env)->GetStringUTFChars(env, str, 0); double scaleD =(double)scale; PAINTSTRUCT ps; HDC hdc = GetDC(hWnd); HBITMAP hbm = (HBITMAP)LoadImage( NULL, c_string , IMAGE_BITMAP, 0,0,LR_LOADFROMFILE ); HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbm); BITMAP bm; GetObject(hbm, sizeof(bm), &bm); SetStretchBltMode(hdc, HALFTONE); SetBrushOrgEx(hdc,x,y,NULL); StretchBlt(hdc,x,y,bm.bmWidth*scaleD,bm.bmHeight*scaleD,hdcMem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); ReleaseDC (hWnd,hdc); }Kurz gesagt möchte ich über diese funktion ein Bild in ein Fenster eines anderen Programmes malen. Das Bild soll dazu auch noch entsprechend eines Parameters verkleinert werden. Die funktion tut auch genau das, was sie machen soll, nur gibt es Probleme. Ich rufe diese Funktion sehr häufig auf, ca. 4 mal pro Sekunde. Irgendwann, so nach 10-15minuten fängt der PC an zu spinnen, er wird langsam und dann stürzen sogar Programme ab und vorallem geht auf einaml der soundDevice nicht mehr (Winamp kann nichts mehr abspielen z.B.). Ich bin jetzt auf der Suche, woran das liegt. Es ist sicher dass dies mit meinem Programm zusammenhängt, nur ich weiß nicht an was es liegt. Kann es sein, dass diese Funktion immer wieder die Bilder (ca.8kb groß) einliest und im Speicher hält? Dass dann nach 10minuten einfach der Speicher zugemüllt ist ?
Gibt es eine Methode, wie ich nach jedem Aufruf der Methode die ganzen Bilder usw nochmal freigeben kann?Dazu noch eine allgmeine Frage: Wenn ich in C ein Array definiere (z.B. aus char) muss ich dieses Array explizit wieder freigeben oder macht er es automatisch?
-
Da du nur ein Bitmap immer wieder aus einer dateil lädst, solltest du es irgendwo zwischenspeichern(z.B.: Als static-variable(in der Funktion))
und später immer wieder das bereits bekannte HBITMAP nutzen(Der Speicherverbrauch von einem HBITMAP ist relativ unwichtig, falls doch einmal initialiserungsfunktion aufrufen, und nach dem gebrauch deinitialisierungsfunktion aufrufen...).Hier noch veranschaulicht:
JNIEXPORT void JNICALL Java_MainClass_NewJFrame_paint(JNIEnv *env, jobject obj, jint handle, jint x, jint y, jdouble scale,jstring str) { HWND hWnd = (HWND)handle; const char *c_string = (*env)->GetStringUTFChars(env, str, 0); double scaleD =(double)scale; PAINTSTRUCT ps; HDC hdc = GetDC(hWnd); static HBITMAP hbm = (HBITMAP)LoadImage( NULL, c_string , IMAGE_BITMAP, 0,0,LR_LOADFROMFILE ); // Wird beim der esten ankunft von EIP hier aufgerufen. HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbm); BITMAP bm; GetObject(hbm, sizeof(bm), &bm); SetStretchBltMode(hdc, HALFTONE); SetBrushOrgEx(hdc,x,y,NULL); StretchBlt(hdc,x,y,bm.bmWidth*scaleD,bm.bmHeight*scaleD,hdcMem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteDC(hdcMem); ReleaseDC (hWnd,hdc); }
-
Mal eine frage:
Sieht der Code auch in deinen Dateien so gräßlich aust oder ist das copy-paste und die forumsformatierung?
-
Musst die via LoadImage () geladene Bitmap nach "Gebrauch" auch wieder freigeben :
HBITMAP hbm = (HBITMAP)LoadImage( NULL, c_string , IMAGE_BITMAP, 0,0,LR_LOADFROMFILE ); ... DeleteObject (hbm);
-
Ahh jetz weiß ich was c_str bedeutet, so erübrigt sich die Frage, dass jemand der Lesen kann klar im Vorteil ist, wobei ich gerade diese Kohlhaas Massenpostings gesehen habe, und sagen muss, dass diese Art der Verwendung der Hypotaxe mir wirklich - im Großem und Ganzem - zusagt, obwohl ich eine Vermüllung des Forums misbillige, wobei ich mir eingestehen muss, dass ich das gerade, durch meinen nicht-enden-wollenden Satz, selbst getan habe, obwohl ich mir bewusst war, dass sobald ich etwas von Hypotaxe höre, ich nicht aufhören kann weiterzuschreiben, dies jedoch gegen jeden Sinn und Verstand dennoch mache.
-
tschuldigung für die formatierung, aber so stehts auch in meinem Texteditor drin ^^
also es handelt sich bei jedem Aufruf um ein anderes Bild (naja es sind ca 50 Bilder, die vorkomemn können). Ist es dann besser das mit der static Vairable zu machen oder immer mit DeleteObject?
und wie ist das nochmal mit Varaiblen und Arrays in C, müssen die nicht auch manuell nochmal freigegeben werden?
-
Hääh wo is meine antwort hin?
Wahrscheinlich wieder der vorschau knopp.Also da du immer wieder neue bilder lädst solltest du die immer am ende der funktion mit DeleteObject freigeben.
Du könntest natürlich auch erst einmal alle 50 bilder in ein array laden, und dann die HBITMAPs von da benutzen