2

I use MathLink to send and receive independent mma expressions from a C++ application as strings.

std::string expression[N];
// ...
for(int i = 0; i < N; ++i) {
    MLPutFunction(l, "EnterTextPacket", 1);
    MLPutString(l, expression[i].c_str());
    MLEndPacket(l);

    // Check Packet ...

    const char* result;
    MLGetString(l, &result);

    // process result ...

    MLDisownString(l, result);
}

I would expect that MLDisownString frees the used memory except that it doesn't.

Any ideas?

rcollyer
  • 10,475
  • 4
  • 48
  • 75
bbtrb
  • 4,065
  • 2
  • 25
  • 30

2 Answers2

6

Ok. Posting this as an answer, because I believe the odds you are using version 5 or below are pretty low:

`As of Version 6.0, MLDisownString() has been superseded by MLReleaseString()`

Check it here

Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • Thanks, this helps quite a bit. Shows, how long I haven't used this small piece of code. Somehow, the memory still grows much more than I would expect, I've tried to throw in `ClearSystemCache[]`, to no avail ... – bbtrb Jun 17 '11 at 17:14
1

First of all, I should point out such parameter as $HistoryLength. Setting it to zero often allows to reduce memory requirements considerably:

$HistoryLength = 0

At the same time, it is known problem with the MathKernel process that it accumulates system memory in long computations and does not release it.

The only way to ultimately solve the problem it to restart the kernel when it takes too much memory or when the amount of available free physical memory becomes too small. This task can be automatized.


If you have not tried Mathematica 8 yet, it may be worth a try, since, according to Oliver Ruebenkoenig:

For version 8 the memory allocator has been rewritten and improved.

(What a small sentence for such a huge endeavor and such a fine execution)

But I have not tried the version 8 yet and cannot say anything on it.

Alexey Popkov
  • 9,355
  • 4
  • 42
  • 93
  • How do you automatize restarting the kernel? Was it covered in an earlier SO question? If not, and if the answer is longer than a comment's worth, I'll post a new question so that you can answer it there. – abcd Jun 18 '11 at 14:46
  • @yoda I don't know if it was covered on SO, but one way (the one I have used when I needed this) is to start a parallel kernel (programmatically) and control it from a master kernel, restarting it (the slave kernel) whenever necessary or periodically. But Alexey probably has something more sophisticated up his sleeve! – acl Jun 18 '11 at 15:06
  • 1
    @yoda It was not covered by previous SO questions and @acl is right: the solution is to use slave kernel for computations and restart it from the master kernel when the rest of free memory becomes too low. I have implemented this for 32bit versions of Windows using NETLink. So if you are interested in such solution it it worth to create a separate question on it. – Alexey Popkov Jun 19 '11 at 01:30