garbage collection is not working with []gocv.Mat - opencv

Assume that the img is a 3 channel Mat in the code.
There is a memory leak with the code.
I guess that the pointers(reference) in the slice "matsplits" are not deleted with garbage-collection in go. How can I fix it?
for{
matsplits := gocv.Split(img)
matsplits[0].Close()
matsplits[1].Close()
matsplits[2].Close()
}
Kind of above codes cause memory leak. I am sure that the Mat objects in imgarr are closed, but the memory usage is still growing up. Why?
Update: part of codes in my project
processed := 0
for processed < proc.imgNumber {
grayhconcatImg := <-proc.processedImg[0][chindex]
var roiList roilist
var numStartPosList numStartPos
for x := 0; x < 11520-w; x++ {
test := gocv.NewMat()
testRegion := grayhconcatImg.img.Region(image.Rect(x, 0, x+w, h))
gocv.BitwiseXor(chimg, testRegion, &test)
testRegion.Close()
//testsplit := gocv.Split(test)
test.Close()
//testsplit[0].Close()
//testsplit[1].Close()
processed++
}
The memory leak occurs if "testsplit"'s are unmarked.
len(testsplit) is 2.
I have checked that testsplit[0] and testsplit[1] have been closed correctly after testsplit[i].Close().

After Close(), the memory will be clear partly after the gc comes.
Check it like
matsplits := gocv.Split(img)
matsplits[0].Close()
matsplits[1].Close()
matsplits[2].Close()
runtime.GC()
exec like GODEBUG=gctrace=1 go run main.go 2>xx.log
and you can find the what gc actual do in xx.log

Related

Reading Program Memory In AHK

So I am working on a program to read values from a game (Mitos.is: The Game).
It is similiar to Agar.io
You have a size (mass), and I want to get the mass amount, it is a program, not an online game like Agar.io.
I have found this Auto Hotkey script:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
ReadMemory(MADDRESS=0,PROGRAM="",BYTES=4)
{
Static OLDPROC, ProcessHandle
VarSetCapacity(MVALUE, BYTES,0)
If PROGRAM != %OLDPROC%
{
WinGet, pid, pid, % OLDPROC := PROGRAM
ProcessHandle := ( ProcessHandle ? 0*(closed:=DllCall("CloseHandle"
,"UInt",ProcessHandle)) : 0 )+(pid ? DllCall("OpenProcess"
,"Int",16,"Int",0,"UInt",pid) : 0)
}
If (ProcessHandle) && DllCall("ReadProcessMemory","UInt",ProcessHandle,"UInt",MADDRESS,"Str",MVALUE,"UInt",BYTES,"UInt *",0)
{ Loop % BYTES
Result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)
Return Result
}
return !ProcessHandle ? "Handle Closed:" closed : "Fail"
}
mass := ReadMemory(Address here, "Mitos.is: The Game")
MsgBox, %mass%
It works seamlessly but there is one slight problem, in Cheat Engine I took the liberty of finding the base address as shown below:
So I took the address circled here:
And inserted that into the program where it says "Address Here", correct me if this is not the right address, but when I restart the game and run my script it says "Fail", but in Cheat Engine the address is still valid. Help?
Check the address if it changes after restarting the game, or do not restart game just run the script without restart and you haven't defined bytes so try following,
ReadMemory(MADDRESS=0, PROGRAM="", BYTES=4 )
mass := ReadMemory("0x123456", "Mitos.is: The Game", "4")
"PROGRAM" should be correct window title use spy to get correct window title, address has to be in hex value i.e. "0x15B29DD0", I don't know how your cheat engine reads program memory address.

Strange behavior using TPointSeries.Clear

(Delphi 6 with TChart, Win XP)
I'm getting erratic behavior trying to clear the points from a point series, and of course, this code used to work.
Basically, this part of my program generates 5 data points and plots them. When I try to clear them using OSC_Series.Clear I get a "List index out of bounds [0]" error.
I checked to make sure there was nothing odd about the values I was plotting. All is good there. Then I tried different things to try to isolate and work around the problem.
Here's some code.
type
TksGraph_DataFrm = class(TForm)
.
.
.
private
OSC_Series: TPointSeries
public
end;
procedure TksGraph_DataFrm.cat7AnalysisInitialize(var P:TTest_Project);
begin
// Do a bunch of stuff.
// Set up the analysis data points series.
OSC_Series:=TPointSeries.Create(self);
AnalysisChart.AddSeries(OSC_Series);
with OSC_Series do
begin
Title:='';
HorizAxis:=aBothHorizAxis;
VertAxis:=aBothVertAxis;
SeriesColor:=clRed;
Pointer.Brush.Color:=clYellow;
Pointer.HorizSize:=4;
Pointer.VertSize:=4;
Pointer.Style:=psRectangle;
Pointer.Visible:=true;
LinePen.Color:=clBlack;
LinePen.Width:=1;
Linepen.Visible:=true;
ShowInLegend:=false;
XValues.Order:=LoNone;
end;
end;
procedure TksGraph_DataFrm.cat7AnalysisRefresh(var P:TTest_Project);
var X,Y:single;
begin
X:= some value
Y:= some value
// Plot the result.
OSC_Series.AddXY(X,Y);
showmessage(
'Count = '+inttostr(OSC_Series.Count)+#13+
'X = '+FloatToStr(X)+#13+
'Y = '+FloatToStr(Y)+#13+
'Plot-X = '+FloatToStr(OSC_Series.XValue[OSC_Series.Count-1])+#13+
'Plot-Y = '+FloatToStr(OSC_Series.YValue[OSC_Series.Count-1]));
end;
Here is the routine I to use to reset the series. I'm including code that does and does not work.
procedure TksGraph_DataFrm.cat7AnalysisClear(var P:TTest_Project);
var i:integer;
begin
// This should work, but it gives me the list out of bounds error
// unless the count is 0.
OSC_Series.Clear;
// This does not work, for obvious reasons. I get a "list out of
// bounds [3] for this one.
for i:=0 to OSC_Series.Count - 1 do OSC_Series.Delete[0];
// It seems this should work, but again I get the out of bounds [0]
// error.
repeat
OSC_Series.Delete(0);
until OSC_Series.Count = 0;
// This works. Don't ask me why.
showmessage('A - '+inttostr(OSC_Series.Count));
OSC_Series.Clear;
showmessage('B - '+inttostr(OSC_Series.Count));
// This also works.
sleep(2000);
OSC_Series.Clear;
// This does not work.
sleep(1000);
OSC_Series.Clear;
end;
I'm stumped, obviously.
This smells like the code is working with an object (OSC_Series) which has been destroyed and the memory then re-used for something else. When you then use the stale reference to that memory you get unexpected and unpredictable results.
Where is OSC_Series free'd ?
I would check all such places and make sure that you do not attempt to use the OSC_Series reference after it has been free'd.
Note also that since the series is owned by the form it could be that the form itself is contriving to executing code in events after it has destroyed its owned components (including this series).
OK, dumb and not dumb.
I experimented with where I put the showmessage statement. I found I could only avoid the error if that statement came after the OSC_Series.Clear statement. I kept moving that statement back until it was after the call to the AnalysisRefresh routine, which is in a button's OnClick event handler. This means that none of the code in the refresh, enable, or update routines was causing this.
Stepping back a bit, if the AnalysisRefresh routine fails the user is shown a message. After that box is closed OSC_Series.Clear is called. If I close the box by pressing SPACE or ENTER on the keyboard... no error. If I use the mouse, error.
The chart behind the mouse has an OnMouseMove event where I display the mouse position on a status bar. I also display a hint if the mouse is near a plotted point. After clicking the message box with a mouse to close it the OnMouseMove event is called and by the time it gets to where it can display the hint, the plotted point is gone, and... error.
So, it seemed like an almost random error, but it wasn't. The trigger was just somewhere else entirely. That's you my try/except block wasn't catching the error. EurekaLog was catching it, but in a different procedure far, far away. (Deltics' answer was pretty close.)
Thanks for your help and suggestions.
Dang it if some days I can push hundreds of lines of code with no problems, then something like this pops up and it costs me near two days.

Memory Not Given Back Until Files Deleted?

We ran into a strange problem with some of our in-house developed applications and thought it was something deep in the code but then we wrote a quick sample to test it, we experienced the same issue.
Here's the code for the sample:
#include <stdio.h>
int main(void)
{
int i;
int j;
int COUNT = 750000;
double x[100];
double y[100];
FILE *OutputFile1;
FILE *OutputFile2;
FILE *OutputFile3;
FILE *OutputFile4;
FILE *OutputFile5;
FILE *OutputFile6;
FILE *OutputFile7;
FILE *OutputFile8;
FILE *OutputFile9;
OutputFile1 = fopen("Output_file_1.dat","w");
OutputFile2 = fopen("Output_file_2.dat","w");
OutputFile3 = fopen("Output_file_3.dat","w");
OutputFile4 = fopen("Output_file_4.dat","w");
OutputFile5 = fopen("Output_file_5.dat","w");
OutputFile6 = fopen("Output_file_6.dat","w");
OutputFile7 = fopen("Output_file_7.dat","w");
OutputFile8 = fopen("Output_file_8.dat","w");
OutputFile9 = fopen("Output_file_9.dat","w");
/* Do stuff in here */
/* Initialize the arrays */
for( i = 0; i < 100; i++)
{
x[i] = 2.50 * (double)i;
y[i] = 10.0 * (double)i;
}
printf("Initialized the x and y arrays\n");
/* Write junk to files */
for( i = 0; i < COUNT; i++)
{
printf("Outer loop %d\n", i);
for( j = 0; j < 100; j++)
{
fprintf(OutputFile1," %e", x[j]);
fprintf(OutputFile2," %e", x[j]);
fprintf(OutputFile3," %e", x[j]);
fprintf(OutputFile4," %e", x[j]);
fprintf(OutputFile5," %e", x[j]);
fprintf(OutputFile6," %e", y[j]);
fprintf(OutputFile7," %e", y[j]);
fprintf(OutputFile8," %e", y[j]);
fprintf(OutputFile9," %e", y[j]);
}
fprintf(OutputFile1,"\n");
fprintf(OutputFile2,"\n");
fprintf(OutputFile3,"\n");
fprintf(OutputFile4,"\n");
fprintf(OutputFile5,"\n");
fprintf(OutputFile6,"\n");
fprintf(OutputFile7,"\n");
fprintf(OutputFile8,"\n");
fprintf(OutputFile9,"\n");
}
/* End doing stuff here */
fflush(OutputFile1);
fclose(OutputFile1);
fflush(OutputFile2);
fclose(OutputFile2);
fflush(OutputFile3);
fclose(OutputFile3);
fflush(OutputFile4);
fclose(OutputFile4);
fflush(OutputFile5);
fclose(OutputFile5);
fflush(OutputFile6);
fclose(OutputFile6);
fflush(OutputFile7);
fclose(OutputFile7);
fflush(OutputFile8);
fclose(OutputFile8);
fflush(OutputFile9);
fclose(OutputFile9);
return(0);
}
So, here's what happens when you run this. If you run this in one terminal window and run top in another while it's running, you'll notice your memory being eaten away. It takes about 8 minutes for it to run and when it's finished, the system doesn't give the memory back, until the files are deleted. Once the files are deleted, all of the memory is released back to the system.
It's just C with the latest gcc compiler, CentOs 6.3.
Are we missing something?
Thanks!
"The system doesn't give the memory back". How do you know? There is a difference between "memory reported as free by top", and "memory you can use". This is because disk I/O is stored in cache when possible - that way, if you need to use the same file again, the information is already available in memory - faster to access. Once you delete a file, it's no longer useful to keep in cache - so the cache is cleared.
Another way to look at this is to use the free command. Doing this on my Linux box, I see the following:
total used free shared buffers cached
Mem: 66005544 65559292 446252 0 199832 60332160
-/+ buffers/cache: 5027300 60978244
Swap: 1044216 1884 1042332
The key line is the one that says "-/+ buffers/cache" . You can see that the first line tells me "446M free" - not a lot on a 64G machine. But the second line says "only joking, you have 60 G free". That is the real "free memory".
See whether that line "gives back memory" without having to delete the files. I think you will find it does.
The system caches these files for quick access at the next time. Since the memory isn't used by an application it's used for caching. The cache is freed if the files are gone or an other application needs more memory to run.
See: Linux Memory Management

Delphi GLScene export scene as stl

I have a GLScene project. In the SceneViewer I import some stl files as freeform.
The user can interact with this objects (move and rotate them with mouse).
Now I have to export this whole Scene to one stl file, so the position and the rotation of the freeforms should be like in the Scene after this export ("merge").
I found this thread about the same problem: Export "Scene" to STL File but this creates an broken stl file (tried open with meshlab).
I hope there is some idea for creating a solution.
If somebody knows a solution for another 3d-file format, it will be great too.
I have found the solution :-)
the link in the answer is nearly right,
but i have to calculate the header information (count of faceletts) in an other way.
now i use a loop an calculate the header before writing thats all.
Sometimes the solution is so near.
var j :integer ;
var i:integer;
var header: TSTLHeader;
var dataFace: TSTLFace;
var list: TaffineVectorlist;
//objects = list of steFreeform objects
//astream = created stream
for j := 0 to objects.count - 1 do
begin
list := TGLFREEForm(objects[j].MeshObjects.ExtractTriangles;
header.nbfaces :0 header.nbFaces + list.count div 3 ;
end;
aStream.write(header.SizeOf(header));
//rest see above link in the question

TDelphiTwain component, corrupts delphi form (dfm file)

I have downloaded opensource delphi twain component (TDelphiTwain).
The interesting thing is, that when placed and saved on the form it creates bad dfm entry for itself.
object DelphiTwain: TDelphiTwain
OnSourceDisable = DelphiTwainSourceDisable
OnSourceSetupFileXfer = DelphiTwainSourceSetupFileXfer
TransferMode = ttmMemory
SourceCount = 0
Info.MajorVersion = 1
Info.MinorVersion = 0
Info.Language = tlDanish
Info.CountryCode = 1
Info.Groups = [tgControl, tgImage, tgAudio, MinorVersion]
Info.VersionInfo = 'Application name'
Info.Manufacturer = 'Application manufacturer'
Info.ProductFamily = 'App product family'
Info.ProductName = 'App product name'
LibraryLoaded = False
SourceManagerLoaded = False
Left = 520
Top = 136
end
The problem is with the line:
Info.Groups = [tgControl, tgImage, tgAudio, MinorVersion]
There are only three possible elements:
tgControl, tgImage and tgAudio
It adds MinorVersion everytime I Save the form.
When the app is run I get the error that there is invalid property for Info.Groups.
When i rmeove the bad part manually and without leaving dfm file the app starts ok.
I looked in the internet and there was one inquire regarding these strange issue, unfortunately it hasn't been resolved.
I think that there is some sort of memory corruption. In the post in teh internet, strange signs were displayed ...
Has anyone worked with that component or could give me some hint how this could be fixed?
The error seems to be in TTwainIdentity.GetGroups where result is not initialized. You can try to change the code by replacing
Include(Result, tgControl);
with
Result := [tgControl];
You have to recompile the package to make this change work inside the IDE.
I don't know the component, but I think the problem lies in the TTwainIdentity.GetGroups method. It starts like this:
begin
Include(Result, tgControl);
This means that it assumes that Result is initialized to an empty set. However, Result may contain garbage, and not necessarily an empty set. Change this method to look like this:
function TTwainIdentity.GetGroups(): TTwainGroups;
{Convert from Structure.SupportedGroups to TTwainGroups}
begin
Result := [tgControl];
if DG_IMAGE AND Structure.SupportedGroups <> 0 then
Include(Result, tgImage);
if DG_AUDIO AND Structure.SupportedGroups <> 0 then
Include(Result, tgAudio);
end;
Some result types will not throw a compiler warning about not being initialized, but that doesn't mean they are empty. Same goes, for instance, for strings.
See also: http://qc.embarcadero.com/wc/qcmain.aspx?d=894
But still, it is odd that this happens. Apparently, Delphi tries to find the name of the given item in the set and accidentally finds the name of another property. It seems to me that quite some checks in writing the dfm are missing if this happens. :)

Resources