View Issue Details

IDProjectCategoryView StatusLast Update
0003730JEDI VCL00 JVCL Componentspublic2006-06-28 07:34
ReporterLiorFAssigned Toivan_ra 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.10 
Target VersionFixed in Version3.30 
Summary0003730: JvInterpreter memory leak
DescriptionWe are exstensively using JvInterpreter to run scripts and if we leave our program to run for a long time, eventually it runs out of memory.
FastMM memory leak reporting points to JvInterpreter as the culprit. The memory gets clogged with huge amounts of strings. Stack trace reads:
[System][@GetMem]
[System][@NewAnsiString]
[System][@LStrFromPCharLen]
[JvInterpreterParser][TJvInterpreterParser.Token]
[JvInterpreter][TJvInterpreterExpression.ParseToken]
It is strange that strings aren't freed. Shouldn't there be reference counting?

Any solutions?
Additional InformationWe use Delphi6
TagsNo tags attached.

Relationships

related to 0002073 resolvedivan_ra OLE automation support does not work correctly in JvInterpreter 

Activities

ivan_ra

2006-05-28 11:20

developer   ~0009358

strings in TJvInterpreterParser.Token are allocated by SetString procedure. If so, they are automatically free by system string manager, and there should not be memory leak in function TJvInterpreterParser.Token.
It's may be:
1) leak in your application
2) wrong strings/variants in D6
Could You post some code where called JvInterpreter functions? Do You create TJvInterpreter for every call of script, or use 1 instance?

remkobonte

2006-05-28 16:31

developer   ~0009359

If I use the following script:

var
  A: array [0..10] of Integer;
begin
  Result := A[1];
end;

and test it with the demo program in examples\RaLib\RaInterpreter, I also get a memory leak. The allocation is at the same spot as LiorF reported, specifically the last NextToken call in TJvInterpreterFunction.InterpretIdentifier.

Something seems to go wrong in the following InternalSetValue(Identifier) call. The code is hard to read for me, but I think the problem in this case is in the JvInterpreterVarCopy procedure (parameter Source is then the A array and Dest is the 'A' string, the cast bypasses the reference count stuff)

I think :)

ivan_ra

2006-05-29 03:52

developer   ~0009360

Remko, you are right.
JvInterpreterVarCopy is leaky because it bypasses the reference count stuff for varArray and varRecord types.
To release reference we must call VariantClear for Dest variable (look at System._VarCopy as example). So, I suggest to add VarClear(Dest) into JvInterpreterVarCopy.
This is patch for JvInterpreter.pas. It works fine with my progs.

for LiorF: could You test this patch with your program?

2006-05-29 03:52

 

JvInterpreter.pas.patch (478 bytes)
Index: JvInterpreter.pas
===================================================================
--- JvInterpreter.pas	(revision 10609)
+++ JvInterpreter.pas	(working copy)
@@ -2512,7 +2512,10 @@
 procedure JvInterpreterVarCopy(var Dest: Variant; const Source: Variant);
 begin
   if (TVarData(Source).VType = varArray) or (TVarData(Source).VType = varRecord) then
+  begin
+    VarClear(Dest);
     TVarData(Dest) := TVarData(Source)
+  end
   else
     Dest := Source;
 end;

LiorF

2006-05-30 07:01

reporter   ~0009361

Seems to have fixed the problem. Great job and thanks for the fast response!
I will report if I see any additional problems.

ivan_ra

2006-05-30 07:22

developer   ~0009362

This is now in SVN

LiorF

2006-06-04 02:24

reporter   ~0009374

Last edited: 2006-06-04 02:25

Well, looks like it isn't the end of the story. FastMM memory leak reporting reports nothing significant, but the program still leaks memory. We left it running for a few days and it ate all the memory. FastMM reported nothing of significance. However just looking at the program's memory allocation with Task Manager shows that the memory allocation linearly increases with time. This happens only when we use the script. Without it (and with the program performing the same operations as defind by the script) the memory allocation remains constant.

ivan_ra

2006-06-05 06:04

developer   ~0009381

records in JvInterpreter are still leaky. Do You use any record types in your scripts ? (for example, TPoint)

LiorF

2006-06-05 06:37

reporter   ~0009382

I don't use records. Here is an example script:

var
  r:variant;
begin
  r:=func('xyz');//Call to a function that returns a dynamic array of double
  Result:=r[0];
end;

ivan_ra

2006-06-05 10:24

developer   ~0009388

This is new incremental patch (fixes memory leak with arrays and records when they returns from function). The key to solve problem is JvInterpreterVarFree call.
Please try this patch and report results.
Patch also includes issue 0002073 and some optimisation

2006-06-05 10:25

 

JvInterpreter.pas.patch1 (3,365 bytes)

ivan_ra

2006-06-09 05:48

developer   ~0009541

Last edited: 2006-06-09 05:53

This is script illustrating memory leak for records (for jvInterpreterTest program). Requires {$DEFINE JvInterpreter_DEBUG} in head of JvInterpreter.pas

unit a;

procedure main;
var
  pPoint: TPoint;
  i:integer;
begin
  for i:=0 to 10000 do
    pPoint:=Point(0,0);
end;

end.

there is no leak with patch. The same thing with functions returning arrays.
The last patch also include some paranoidal JvInterpreterVarFree calls. I think thats enough.

2006-06-09 05:49

 

JvInterpreter.pas.patch2 (3,924 bytes)

LiorF

2006-06-19 03:37

reporter   ~0009598

I implemented all the changes in patch2 and the leak still persists. I didn't touch patch1. Patch2 replaces it, right?

Try running the script I posted earlier.

ivan_ra

2006-06-19 05:56

developer   ~0009600

Last edited: 2006-06-19 06:15

may be wrong adapter for "func"?
there is no leak in such script:

unit a;

procedure main;
var
  a:variant;
  i:integer;
begin
  for i:=0 to 100000 do
    a:=VarArrayCreate([0,9],varDouble);
end;
end.

please check latest revision. patch2 now in SVN

LiorF

2006-06-20 02:22

reporter   ~0009610

I downloaded all the files from the SVN and compiled the package.
The script in your example produces a leak.
Create a loop in your program that runs the script. Run the script in your example (with or without the loop) and monitor the memory allocation with Task Manager. It rises linearly with time.

2006-06-20 06:32

 

Leak.zip (2,879 bytes)

ivan_ra

2006-06-20 06:36

developer   ~0009612

Cant reproduce. There is no leak in my example (Leak.zip). Tested in D5 and D9

LiorF

2006-06-22 03:39

reporter   ~0009615

I tested your example program on several machines. On some of them it produces a leak, while on others it doesn't. It's very strange. In cases where the leak exists, it isn't reported by the program, but can only be seen in the task manager.
All the machines where the leak occurs have the same installation of Delphi 6 and JVCL. Also, no other program suffers from the leak. It happens only with JvInterpreter.
Any ideas?

anudedeus

2006-06-22 04:38

reporter   ~0009616

LiorF, you first reported the issue as being in v.3.10, are you sure you are using the latest daily JVCL build in your project?

ivan_ra

2006-06-22 04:49

developer   ~0009617

Is there any dependance between leak and:
1) operation system (or service pack)
2) processor model
3) something else?

could You test example with another compiler version? I have not D6 but tested it with D5,D7 and D9 - all without leak, winXP pro, home, win2003

LiorF

2006-06-22 15:22

reporter   ~0009630

I will try to test it on more systems and reinstall JEDI and I will report the results.
Results so far:
System 1:
Athlon XP, Windows XP, Delphi 7, JVCL 3.00 unpatched - no leak
System 2:
Pentium 4, Windows XP, Delphi 6, JVCL 3.10 with all JvInterpreter files updated to the latest versions from SVN and package recompiled - leak
System 3:
Pentium 4, Windows XP, Delphi 6, JVCL 3.10 unpatched - leak

anudedeus

2006-06-23 02:15

reporter   ~0009633

Well, then you must updated your files!
All the bug fixes you find here in the Issue Tracker are introduced to the source repository and there is a daily build of the whole library. So today there is already a newer version than the day before and so on.
Please get the latest one from
http://jvcl.sf.net/daily/
and check if the leaks persist.

LiorF

2006-06-27 01:28

reporter   ~0009650

I downloaded the latest versions of jcl and jvcl. I had no luck installing the new jvcl though. It says "Delphi 6 Update 2 is not installed" and quits. It is installed however. Delphi says that it is installed and just in case, I reinstalled it twice. It didn't help.

LiorF

2006-06-27 03:35

reporter   ~0009657

I disabled the version check (set it to always return update 2) and installed JVCL.
The leak persists.

2006-06-27 04:39

 

NoLeak.JPG (115,017 bytes)
NoLeak.JPG (115,017 bytes)

ivan_ra

2006-06-27 04:49

developer   ~0009668

Last edited: 2006-06-27 04:50

I just tested it in D6 - there is no leak (look at screen)
D6 Enterprise build 6.240 update pack 2
JVCL 3.30 from SVN
WinXP Pro v.2002 Service Pack 2
Pentium 4 2.4 GHz
There was no problem with installing JCL and JVCL in D6

LiorF

2006-06-27 04:50

reporter   ~0009669

I tested it on more systems. All of them were Pentium 4 with Delphi 6 Professional and Windows XP Professional. All systems experienced the leak.
Delphi 6 seems the most logial common link, although it can still be something else.

ivan_ra

2006-06-27 04:54

developer   ~0009670

difference between D6 Enterprise and D6 Professional?
Could You test it with D6 Enterprise?

LiorF

2006-06-27 05:20

reporter   ~0009671

I don't have Enterprise. Note that the leak is not reported by the program nor by FastMM. It can be seen from the task manager and from the fact that if you run it for long enough, the system runs out of memory. What can cause such a leak?
I might try tomorrow or in a few days testing it on a system with a different installation of Windows, but with the same installation of Delphi.

ivan_ra

2006-06-27 05:35

developer   ~0009672

This is test example compiled with D6 Ent:
http://niisau.ru/leak/Project1.rar

anudedeus

2006-06-27 05:45

reporter   ~0009673

Guys, I just realised that I had something similar in the past and that wasn't an actual memory leak, but the way that the memory manager or the OS works. By that time I was using the standard Delphi 7 Enterprise memory manager, WinXP Pro.
What I believe is happening is that although the code has requested the memory to be freed, and got an ok as result from the OS, it (the OS) doesn't really fully deallocates it, for performance reasons. That is specially true for very small chunks of data, as it considers that the same memory will be soon used again by the same app.
In my case, I was creating a tstringlist and freeing it, several times in a loop.
Sleuth (the tool I use to find memory leaks) didn't report any leak at all, but looking at task manager it goes up and up and up during the cycle, and even after I got out of the loop (and the variable was local to it), the memory continued to be allocated to my app until the app finished, where everything would be flushed out. No memory leak reports from anybody.
So, I don't believe there is any problem with the code (Jedi), and that's a case of reporting that to the FastMM developers instead and see what they think.

LiorF

2006-06-27 07:21

reporter   ~0009689

This is a possibility. There is however certainly a bug somewhere, as eventually the system runs out of memory and the program crashes. It could be that the bug is in Windows.
Interestingly on one of the systems I tested, there was no problem. It was an Athlon XP with Windows XP professional service pack 2 and Delphi 7.
I also tested it on 4 systems with Pentium 4, Windows XP professional service pack 1 and Delphi 6. All these had the problem. The problem occured with both the default memory manager and fastmm. Also the problem occurs only when we use JvInterpreter. We use lots of other programs and never experienced any such behavior. There must be something in JvInterpreter that triggers it.

ivan_ra

2006-06-27 08:37

developer   ~0009698

Last edited: 2006-06-28 02:21

1) JvInterpreter intensively uses variants and custom variants (for arrays, records, etc)
2) New Variants was firstly introduced in D6. I'm not sure, but perhaps they was leaky and was fixed in latest versions (in D6 Ent Update 2 too), but not in D6 Pro. Thats why I ask You to test leak in any other IDE.
You can also check size or Variants unit from D6 Ent:

Source\Rtl\Sys\Variants.pas: 4991 lines, 153678 bytes
lib\Variants.dcu: 80328 bytes

Source\Rtl\Sys\VarUtils.pas: 1964 lines, 65892 bytes
lib\VarUtils.dcu: 5886 bytes

LiorF

2006-06-28 02:07

reporter   ~0009702

Well, we have much smaller files:
Variants.pas 115,954 bytes
VarUtils.pas 53,108 bytes

ivan_ra

2006-06-28 02:38

developer   ~0009707

OK. This is size of source files from initial installation of D6 (without Update 2).
Please check dcu size
Variants.dcu - 49 402
VarUtils.dcu - 4 010
this is sizes of files from D6 CD
If You have not right Update2 files (Variants.dcu: 80328 bytes and VarUtils.dcu: 5886 bytes), I think this is not JVCL issue and it can be resolved

obones

2006-06-28 02:58

administrator   ~0009709

Also note that Delphi 6 has two Runtime Library updates. So to be sure you have everything in order, you should have installed this:

Delphi 6
General Update 2
Runtime Library Update 2
Runtime Library Update 3

Variants issues are specifically addressed by RTL Update 2.
After this, I agree this issue should be set as "resolved".

LiorF

2006-06-28 05:55

reporter   ~0009710

The thing is I installed these updates in the past. To be sure I now reinstalled them. The insatall goes normally, no errors of any kind. In the end it shows a text file with what was installed and indeed in rtl2 it says that it updated the variants. Variants.pas and variants.dcu however remain unchanged and they are nowhere near the sizes you quoted. Maybe someone can send me the files by mail?

ivan_ra

2006-06-28 06:59

developer   ~0009711

Last edited: 2006-06-28 07:29

I think You need to try google search, for example
http://www.google.com/search?q=Delphi+6+Runtime+Library+Update+3

:)

RTL 2 Files:
Source\Rtl\Sys\Variants.pas: 5557 lines, 169 260 bytes
lib\Variants.dcu: 86 796 bytes

Source\Rtl\Sys\VarUtils.pas: 2258 lines, 75 756 bytes
lib\VarUtils.dcu: 13 130 bytes

after installing all patches please report about leak to resolve this issue

LiorF

2006-06-28 07:13

reporter   ~0009712

Problem solved!
Apparently the updates were installing absoultely nothing even though they reported as if everything was installed. They were unable to rewrite any files. I don't know what caused it. It could be antivirus or something running in the background. So I let them install to a empty Delphi directory tree and took all the new files from there. The leak disappeared.
Thank you for all the help.

ivan_ra

2006-06-28 07:33

developer   ~0009714

fixed 06-19-06 (message 9600)

Issue History

Date Modified Username Field Change
2006-05-28 07:34 LiorF New Issue
2006-05-28 11:20 ivan_ra Note Added: 0009358
2006-05-28 11:20 ivan_ra Status new => feedback
2006-05-28 16:31 remkobonte Note Added: 0009359
2006-05-29 03:52 ivan_ra Note Added: 0009360
2006-05-29 03:52 ivan_ra File Added: JvInterpreter.pas.patch
2006-05-30 07:01 LiorF Note Added: 0009361
2006-05-30 07:22 ivan_ra Status feedback => resolved
2006-05-30 07:22 ivan_ra Resolution open => fixed
2006-05-30 07:22 ivan_ra Assigned To => ivan_ra
2006-05-30 07:22 ivan_ra Note Added: 0009362
2006-05-30 08:44 ivan_ra Status resolved => feedback
2006-05-30 08:44 ivan_ra Resolution fixed => reopened
2006-05-30 08:44 ivan_ra Status feedback => resolved
2006-05-30 08:44 ivan_ra Fixed in Version => Daily / SVN
2006-05-30 08:44 ivan_ra Resolution reopened => fixed
2006-06-04 02:24 LiorF Status resolved => feedback
2006-06-04 02:24 LiorF Resolution fixed => reopened
2006-06-04 02:24 LiorF Note Added: 0009374
2006-06-04 02:25 LiorF Note Edited: 0009374
2006-06-05 06:04 ivan_ra Note Added: 0009381
2006-06-05 06:37 LiorF Note Added: 0009382
2006-06-05 10:24 ivan_ra Note Added: 0009388
2006-06-05 10:25 ivan_ra File Added: JvInterpreter.pas.patch1
2006-06-09 05:48 ivan_ra Note Added: 0009541
2006-06-09 05:49 ivan_ra File Added: JvInterpreter.pas.patch2
2006-06-09 05:53 ivan_ra Note Edited: 0009541
2006-06-09 05:53 ivan_ra Note Edited: 0009541
2006-06-09 06:16 obones Relationship added related to 0002073
2006-06-19 03:37 LiorF Note Added: 0009598
2006-06-19 05:56 ivan_ra Note Added: 0009600
2006-06-19 06:15 ivan_ra Note Edited: 0009600
2006-06-20 02:22 LiorF Note Added: 0009610
2006-06-20 06:32 ivan_ra File Added: Leak.zip
2006-06-20 06:36 ivan_ra Note Added: 0009612
2006-06-22 03:39 LiorF Note Added: 0009615
2006-06-22 04:38 anudedeus Note Added: 0009616
2006-06-22 04:49 ivan_ra Note Added: 0009617
2006-06-22 15:22 LiorF Note Added: 0009630
2006-06-23 02:15 anudedeus Note Added: 0009633
2006-06-27 01:28 LiorF Note Added: 0009650
2006-06-27 03:35 LiorF Note Added: 0009657
2006-06-27 04:39 ivan_ra File Added: NoLeak.JPG
2006-06-27 04:49 ivan_ra Note Added: 0009668
2006-06-27 04:50 LiorF Note Added: 0009669
2006-06-27 04:50 ivan_ra Note Edited: 0009668
2006-06-27 04:54 ivan_ra Note Added: 0009670
2006-06-27 05:20 LiorF Note Added: 0009671
2006-06-27 05:35 ivan_ra Note Added: 0009672
2006-06-27 05:45 anudedeus Note Added: 0009673
2006-06-27 07:21 LiorF Note Added: 0009689
2006-06-27 08:37 ivan_ra Note Added: 0009698
2006-06-28 02:07 LiorF Note Added: 0009702
2006-06-28 02:21 ivan_ra Note Edited: 0009698
2006-06-28 02:38 ivan_ra Note Added: 0009707
2006-06-28 02:58 obones Note Added: 0009709
2006-06-28 05:55 LiorF Note Added: 0009710
2006-06-28 06:59 ivan_ra Note Added: 0009711
2006-06-28 07:13 LiorF Note Added: 0009712
2006-06-28 07:29 ivan_ra Note Edited: 0009711
2006-06-28 07:33 ivan_ra Status feedback => resolved
2006-06-28 07:33 ivan_ra Resolution reopened => fixed
2006-06-28 07:33 ivan_ra Note Added: 0009714