2
$\begingroup$

This code causes Mathematica to slowly accumulate memory until it hard crashes my operating system. It does this by overwriting OS memory (windows start going black, graphics drivers start crashing etc.)

Table[RandomImage[1, {1000, 100}, ColorSpace -> "RGB"] 
// TextRecognize // StringLength, 5000] // Total

Compare the above code to this code. This code does not have a memory leak.

Table[RandomImage[1, {1000, 100}, ColorSpace -> "RGB"] 
// ImageMeasurements[#, "Mean"] & , 5000000] // Total

I've done enough testing to be pretty confident the issue with this line is with TextRecognize. My "real" application makes a lot of TextRecognize calls while monitoring computer screens and it always crashes after about an hour of running. I'd like it to run for at least 24 hours reliably.

I'm running 64 bit Windows 10 with 16GB of RAM. I have a machine with 128GB of RAM same problem.

Is there a way to force Mathematica to keep the memory usage in check? Is there an alternative way around this problem?

UPDATE:

Yes this is stupid code. No one actually recognizes text in random data. But, this allows anyone to reproduce the issue I'm seeing without passing around images. Copy paste this into your Mathematica install. Do you see the memory usage grow, so that after half an hour or so you've consumed 32GB of RAM? That's what I'm seeing.

UPDATE2:

I've demonstrated this issue on two completely separate machines [both Windoze 10, one 32Gig, one 64Gig RAM]. Wolfram Research cannot reproduce this issue on their test machine. If someone else could confirm this is an issue for themselves, I'd appreciate it.

Update 3:

I realized that for my specific situation, some of the workarounds proposed in this question: https://stackoverflow.com/questions/8916732/mathematicas-textrecognize-not-up-to-par work great for me. Cross Correlation is (for me) a vastly superior solution than a buggy TextRecognize.

$\endgroup$
11
  • 2
    $\begingroup$ You're trying to recognize text in a random image???? No wonder this impossible task is taking forever! $\endgroup$ Commented Aug 25, 2022 at 2:31
  • 2
    $\begingroup$ @DavidG.Stork you misunderstand the problem. The issue is not time to execute the command. The issue is that the command consumes unlimited memory, when it's pretty clear that similar commands do not. There's a clear memory leak in TextRecognize. That's the issue. $\endgroup$
    – John
    Commented Aug 25, 2022 at 12:24
  • $\begingroup$ @John - you should report this to Wolfram Research, in the end they are the ones who can fix this. $\endgroup$
    – Jason B.
    Commented Aug 25, 2022 at 13:59
  • 1
    $\begingroup$ AFAIK TextRecognize uses a rather outdated version of Tesseract under the hood. It is not suitable for serious applications. I would recommend using a more up-to-date version, perhaps a Python implementation via ExternalFunction. Quick search gives this: pypi.org/project/pytesseract. $\endgroup$ Commented Aug 25, 2022 at 14:21
  • 1
    $\begingroup$ But if for some reason you are forced to use TextRecognize, as a workaround you could call it in a slave kernel and control the memory usage via MemoryAvailable[], killing the slave kernel when it clearly took up too much memory. $\endgroup$ Commented Aug 25, 2022 at 14:28

1 Answer 1

3
$\begingroup$

AFAIK TextRecognize uses a rather outdated version of Tesseract under the hood. It is not suitable for serious applications. I would recommend using a more up-to-date version, perhaps a Python implementation via ExternalFunction. Quick search gives this.

Is there a way to force Mathematica to keep the memory usage in check? Is there an alternative way around this problem?

Yes, but you shouldn't rely on MemoryInUse[] when working with functionality outside of the Mathematica's kernel, because this function reports memory usage only by the main MathKernel process. To prevent system crashes, it is better to monitor the total free memory available for the operating system using MemoryAvailable[].

If for some reason you are forced to use TextRecognize, as a workaround you could call it in a slave kernel and control the memory usage via MemoryAvailable[], killing the slave kernel when it clearly took up too much memory.

A long time ago I implemented similar functionality using only low-level functions. A lot has changed since then, but perhaps these old discussions might still be of some interest:

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.