Hi, I was trying to do this thing:
I wish to have the clips environment running in a loop in a separated thread and from the main thread send commands to the environment
The problem is that when everything is running, without doing nothing, the memory occupation start increasing about 1MB per second, and looking to a memory snapshot, it says that the object CLIPSNET.CaptureRouter is continuosly allocating instances of about 160 bytes but at a rate of about 5000 per second.
Below there is the minimal code to reproduce the problem: what I'm doing wrong?
//Program.cs// See https://aka.ms/new-console-template for more informationusingTestSistemaEsperto;ClipsEngineclipsEnvironment=newClipsEngine();TaskclipsTask=newTask(()=>{try{clipsEnvironment.Loop("..\\..\\..\\RuleBase\\");}catch(Exceptionex){Console.WriteLine(ex.ToString());}});clipsTask.Start();stringline=string.Empty;while(line!="stop"){line=Console.ReadLine()??"stop";if(!string.IsNullOrWhiteSpace(line)){//clipsEnvironment.Commands.Enqueue(line);}}
There was an issue with a strong reference in the router code that prevented the .NET garbage collection from reclaiming memory. See if that fixes your issue.
Hi, I was trying to do this thing:
I wish to have the clips environment running in a loop in a separated thread and from the main thread send commands to the environment
The problem is that when everything is running, without doing nothing, the memory occupation start increasing about 1MB per second, and looking to a memory snapshot, it says that the object CLIPSNET.CaptureRouter is continuosly allocating instances of about 160 bytes but at a rate of about 5000 per second.
Below there is the minimal code to reproduce the problem: what I'm doing wrong?
I can't tell much from just this. Can you provide enough code that I can reproduce the issue? The Target value should be set in this piece of code when the WeakReference is created:
Hi,
I've found what is causing the problem, but I don't know why, I suppose it's related to WeakReference.
Anyways, this is the code that is running in a separated task
Yes, it seems like a plausible explanation that the router is getting garbage collected. I looked through my .NET code and in the cases where I saw routers being used they were either assigned to an member variable of a class or completely used within the scope of a method so they wouldn't be garbage collected when in use. I think what I need to is add a HashSet (or whatever it's called for .NET) to the Environment class and add any routers passed into AddRouter to that set so the garbage collecter won't try to collect them until they've been removed with a DeleteRouter call.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, I was trying to do this thing:
I wish to have the clips environment running in a loop in a separated thread and from the main thread send commands to the environment
The problem is that when everything is running, without doing nothing, the memory occupation start increasing about 1MB per second, and looking to a memory snapshot, it says that the object CLIPSNET.CaptureRouter is continuosly allocating instances of about 160 bytes but at a rate of about 5000 per second.
Below there is the minimal code to reproduce the problem: what I'm doing wrong?
Download these updated files:
CLIPSNET_Router.cpp
CLIPSNET_Router.cpp
From here:
https://sourceforge.net/p/clipsrules/code/HEAD/tree/branches/64x/windows/MVS/CLIPSCLRWrapper/Source/Integration/
There was an issue with a strong reference in the router code that prevented the .NET garbage collection from reclaiming memory. See if that fixes your issue.
Gary
I've changed CLIPSNET_Router.cpp and .h
It is now stable
Thank you
Hi again,
in another project I had defined a new ruoter, and now, after changing those files, I had a null reference exception here:
r is null
This is my implementation of router
Is there something wrong?
Last edit: Davide Archetti 2023-03-03
I can't tell much from just this. Can you provide enough code that I can reproduce the issue? The Target value should be set in this piece of code when the WeakReference is created:
CLIPSCPPRouterBridge::CLIPSCPPRouterBridge(msclr::gcroot<router^> the_Router)
{
m_Router = gcnew WeakReference(the_Router,false);
}</router^>
It would be helpful to know if this is either not initially set or if the value is set to null at some other point.
Hi,
I've found what is causing the problem, but I don't know why, I suppose it's related to WeakReference.
Anyways, this is the code that is running in a separated task
And that code is working correctly. Now, instead of using the line
if instead, I use
now I get the null pointer exception.
Is it because the Garbage Collector has done its work because the Trace router has gone out of scope after exiting the AddRouter function?
Yes, it seems like a plausible explanation that the router is getting garbage collected. I looked through my .NET code and in the cases where I saw routers being used they were either assigned to an member variable of a class or completely used within the scope of a method so they wouldn't be garbage collected when in use. I think what I need to is add a HashSet (or whatever it's called for .NET) to the Environment class and add any routers passed into AddRouter to that set so the garbage collecter won't try to collect them until they've been removed with a DeleteRouter call.
Try these replacement files for the CLIPSCLRWrapper project.
Yes, it works now, no more errors.
Thank you