login about faq
1
1

OK, so I am not one to cry wolf, so believe me when I say that I have tried everything I know how to here...

I know this is a bit long, you might want to skim... this is just most of the steps I have gone through in this exceptionally long day :(

So I had this clever idea to monitor the connectivity between two processes communicating through Chilkat.Socket on different pc's. Not for the application logic, but as an indicator to the end user so that they can see if their are connectivity issues (maybe for troubleshooting?). Kind of like how your cell, or laptop indicates tower, or wireless router signal strength (respectively) in real time. Purely a convenience, but when things went wrong I began to question my entire implementation of the socket object.

It was very simple to implement, I just created a loop that fired every couple of seconds on the client and connected to the server, then used the success of that to formulate a simple display and closed the socket.(JScript BTW)

var strength = [];
connectivity = new bw.Loop(function() {
    var ssl = 0 ,
        ip = 'localhost' ,
        port = 5555 ,
        maxWaitMillisec = 5 ,
        success = socket.Connect(ip , port , ssl , maxWaitMillisec);

    if (success) {

        if (strength.length <= 5)
            strength.push('I');

        socket.Close(10);
    }
    else {
        if (strength.length > 0)
            strength.pop();
    }
    bw.ID('networkDisp').innerText = strength.join('');
})
connectivity.speed(2000);
connectivity.init();

But as I left that alone to go work on other things, when I came back my memory had jumped to 200+mb (on the server app)

So I stripped everything out of both scripts that wasn't necessary (as illustrated by the chilkat example programs) and ran the following

(server)

var listenSocket = new ActiveXObject('Chilkat.Socket');
listenSocket.UnlockComponent('****');
listenSocket.BindAndListen(5555 , 1);

var repeat = function() {

    var connectedSocket = listenSocket.AcceptNextConnection(5);

    if (connectedSocket) {
        connectedSocket.Close(1)
    }

    repeat();
}
repeat();

(client)

var socket = new ActiveXObject('Chilkat.Socket');
socket.UnlockComponent('****');

var repeat = function() {

    var success = socket.Connect('localhost' , 5555 , 0 , 5);

    if (success)
        socket.Close(10);

    repeat();
};
repeat();

I tried other various settings (variations in the maxWaitMillisec, as well as MaxReadIdleMs & MaxSendIdleMs properties) but the server always grew in memory (quite fast) and the client stayed the same. After a while I turned the server off, but I forgot the client, and then all of a sudden line 6 var success = socket.Connect('localhost' , 5555 , 0 , 5); in the client interrupted my research with a crash: "Stack Overflow". No idea where that came from... but I changed the maxWaitMillisec to 0 (after all, the application can hang during testing...) and that stopped that.

So I tried translating to vbscript (I know it's the same activeX, but it seemed worth a shot). Still had the memory leak (as expected). I thought maybe I wasn't giving the socket close enough time, so I extended that to 1000ms, and slept for 1500ms.

set listenSocket = CreateObject("Chilkat.Socket")
listenSocket.UnlockComponent("****")
success = listenSocket.BindAndListen(5555,25)

Function repeat()

    Set connectedSocket = listenSocket.AcceptNextConnection(0)

    If (connectedSocket Is Nothing ) Then
        repeat()
    End If

    connectedSocket.Close 1000
    WScript.Sleep(1500)
    repeat()

End Function

repeat()

Still leaked.

I downloaded the latest activeX (dec 2012), still leaked.

I compiled the JScript with JSC.exe (which if you are unfamiliar requires .net as per my previous issue that you addressed in "Chilkat.FileAccess not marked as "safe for scripting"?"). So I downloaded the latest ChilkatDotNet.dll (dec 2012) and compiled/ran the following

import Chilkat

var listenSocket = new Chilkat.Socket
listenSocket.UnlockComponent('****');
listenSocket.BindAndListen(5555 , 1);

var repeat = function() {

    var connectedSocket = listenSocket.AcceptNextConnection(0);

    if (connectedSocket) {
        connectedSocket.Close(10)
    }

    repeat();
}
repeat();

Leaked... Still.

I have been scouring the reference material to find which property or method I incorrectly allocated, or omitted but all I can figure is the Dispose() method (that I have been waiting about 6 months to be "documented"), and even though I have no idea how to use it I took a shot in the dark. connectedSocket.Dispose() didn't seem to register... but,

The following caused almost an immediate crash

var listenSocket = new ActiveXObject('Chilkat.Socket');
listenSocket.UnlockComponent('****');
listenSocket.BindAndListen(5555 , 1);

var repeat=function() {

    var connectedSocket = listenSocket.AcceptNextConnection(0);

    if (connectedSocket) {
        connectedSocket.Close(1)
    }
    listenSocket.Dispose()
    repeat();
}
repeat();

So I thought maybe if I "dispose" of the object, I should allow the garbage collection to sweep it up, and just call a new instance. And the following actually slowed the "leak" (a bit)

var repeat=function() {

    var listenSocket = new ActiveXObject('Chilkat.Socket');
    listenSocket.UnlockComponent('****');
    listenSocket.BindAndListen(5555 , 1);

    var connectedSocket = listenSocket.AcceptNextConnection(0);

    if (connectedSocket) {
        connectedSocket.Close(1)
    }
    listenSocket.Dispose()
    repeat();
}
repeat();

But, of course, that did not stop it. Since it is undocumented on the chilkat sites I did a google search for "Dispose method" and in the msdn article their was mention of "Important: C++ programmers should read" and I remembered, that chilkat uses the same c++ code for all libs across all platforms, so their must be documentation in http://www.chilkatsoft.com/refdoc/vcCkSocketRef.html about Dispose()... but it doesn't even exist there... so I'm definitely confused... I only mention that so that you understand that: I tried... and I am at my whits end.

What have I omitted, or improperly calibrated in my code?

Keep in mind that while the client doesn't grow, if left unchecked it will eventually cause a stack overflow with var success = socket.Connect('localhost' , 5555 , 0 , 5);

And the server seems to inevitably fail at var connectedSocket = listenSocket.AcceptNextConnection(0);

I know I'm supposed to provide LastErrorText, but it seems to be working until it doesn't, and (the main issue) it works fine but leaks memory... so I honestly don't know where to poll the LastErrorText...

Very sorry for the long post (if I knew what I was talking about maybe it would have been more concise). And thank you for taking the time to consider it.

asked Apr 06 '13 at 02:34

blaze4218's gravatar image

blaze4218
86349


You are correct: The problem was in the ActiveX wrapper. Please try this new build: http://www.chilkatsoft.com/preRelease/ChilkatSocket.zip

link

answered Apr 10 '13 at 16:58

chilkat's gravatar image

chilkat ♦♦
11.8k316358420

Yep, that definitely fixed it. You rock!

My test fires as quick as possible, so it tends to grow about 10-15mb before resetting, but it's running right now as I respond, and it's up to 20000 iterations- and no leak :) Thank you so much!

(Apr 10 '13 at 17:10) blaze4218

It appears that you are calling the repeat() function from within itself. This will eventually fill up the stack because repeat() never reaches the end of the function before calling itself (hence the Stack Overflow error).

You should use a timer or some other event to call repeat(), and then let the repeat() method finish without calling itself recursively.

link

answered Apr 06 '13 at 13:13

jpbro's gravatar image

jpbro ♦
1.1k2618

Yeah, sorry that explains the overflow. I didn't think that through, it's been so long since I've seen that error, I forgot how it applied. But the environment for the test doesn't really have a timer mechanism, the original code used a loop class powered by a timer, that's why it never occurred there. It was late when I finished putting together that post, I didn't mean to focus so much on the overflow. I'm really more concerned with how I'm implementing the socket logic, and if I'm missing something before initializing it, or to properly destroy it. I'm loosing mem, and it's not a bad loop..

(Apr 06 '13 at 13:50) blaze4218

Yeah, I'm seeing about 28kb/connection lingering even after the connection is closed. Unfortunately, I'm not sure what to do to release it.

(Apr 06 '13 at 17:11) jpbro ♦

Well thanks for your independent verification. I guess I'll just wait for the big guy to weigh in now. I can put that process on the back burner for now, my other traffic is no where near enough to trigger something like this, so I'm not too worried. I actually got the idea from your post about monitoring internet connectivity, even used your logic branch to speed up if it looks like we lost the host, so thanks for getting me into this pickle ;)

Oh, and +1 for the overflow catch.

(Apr 06 '13 at 20:32) blaze4218

UPDATE

Ok, so I tried http://www.chilkatsoft.com/p/p_300.asp, but this took quite a bit of research as my jsc compiler runs on .net ver 2. I found a ver 4.0 compiler, and downloaded ChilkatDotNet4.dll and ran the following for the server

import Chilkat
import System

var listenSocket = new Chilkat.Socket
var fac = new Chilkat.FileAccess

listenSocket.UnlockComponent('****');
listenSocket.BindAndListen(5555 , 1);

fac.WriteEntireTextFile('serverLog.txt' , 'begin' , 'ansi')

for (var iter = 0 ; iter<5000 ; ++iter) {

    var connectedSocket = listenSocket.AcceptNextConnection(0);

    if (connectedSocket) {
        connectedSocket.Close(10)
    }

    else {
        fac.OpenForAppend('serverLog.txt')
        fac.AppendAnsi(fac.LastErrorText)
        fac.FileClose()
    }

    GC.Collect()
    GC.WaitForPendingFinalizers();

}

This performed exactly as it should. There must not be a memory leak in AcceptNextConnection. (as I'm sure you anticipated)

Additionally I ran my original test to the point where it acquired 200+ memory again, and killed the client. It took a few hours, but the excess memory finally subsided. So my hypothesis is that the issue might be in the ActiveX wrapper. The windows scripting host gives me no direct access to GC, so all I have been able to try is to nullify the orignial object and create a new one, but as I stated before, that doesn't work... It takes some time, but it eventually clears its own memory, is there any way that you can provide a method to do that programmatically? (assuming I'm correct...)

If not, I will have no choice but to develop this portion of my application with .net (which admittedly would be a fun and welcome challenge...)

link

answered Apr 10 '13 at 15:22

blaze4218's gravatar image

blaze4218
86349

Still don't have an answer (Sorry), but I'm curious about the "leak" too as I've just started work on a web server using the Chilkat Socket for the listener.

When I connect to my CK server using a web browser and hold down F5 (refresh) for a while to open lots of connections, I see the memory use climb steadily. After releasing F5, closing & disposing of all of my accepted sockets, the memory use remains high, even after waiting some time (just in case the memory is being cached for a while).

Is this a leak, or are we missing a step to free memory?

link

answered Apr 09 '13 at 12:41

jpbro's gravatar image

jpbro ♦
1.1k2618

If you wish, please send me a very simple sample snippet of code that demonstrates what you are doing.

(Apr 10 '13 at 09:14) chilkat ♦♦
(Apr 10 '13 at 09:15) chilkat ♦♦

If using C++, it should be possible to see the exact undeleted heap memory on program exit. (This is where you would make sure to call CkSettings::cleanupMemory once at the very end just prior to exit.)

(Apr 10 '13 at 09:18) chilkat ♦♦

I have listed code snippets in JScript, VBScript, and JScript DotNet in my above (original) post that demonstrate the problem. Is there anything you can ascertain based on any of that? I can provide the original code if needed.

(Apr 10 '13 at 11:59) blaze4218
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or __italic__
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Tags:

×60
×5
×3

Asked: Apr 06 '13 at 02:34

Seen: 2,934 times

Last updated: Apr 10 '13 at 17:10

powered by OSQA