How to expand TeX's "main memory size"? (pgfplots memory overload)
The pgfplots
package can be particularly heavy on TeX's memory, especially if you are creating plots with lots of data points. Indeed, there is a section in the pgfplots
manual about expanding TeX's memory. However, that does not mean that expanding TeX's memory is the best solution. Instead, I would recommend using the 'externalization' approach (section 7.1 of the pgfplots
manual).
The idea of externalization is to compile each plot as a separate TeX job. This leads to a graphic which can be used in the main job. Thus each plot has its own memory requirement, separate from all of the other plots. This usually avoids needing to make TeX's memory bigger. At the same time, the resulting files can be kept between TeX runs, which will speed up compilation for the second and subsequent runs. The latest version of the externalization system needs you to do two things. First, you put
\usepgfplotslibrary{external}
\tikzexternalize
in your preamble, to turn the system on. Secondly, you will need to enable 'shell escape'. This is done at the command line by adding the -shell-escape
switch:
pdflatex -shell-escape <filename>
The same can be done in LaTeX editors: there is usually a place in the settings for this type of thing. I'll just add that shell escape does has some security implications: use only with documents that you trust!
Every now and then I have the same problem when compiling certain files. Of course, I have forgotten every time how I solved it in the past. Then, I google and I am getting to this page. Next, I remember that I landed on this page for several times, but, unfortunately, the answers did'nt help me in the past for my kind of problem. To break that Groundhog Day circle, I write down this answer which may help myself (for the next circle) and hopefully other people. The bad news is that it works only (?) for MikTeX
users.
pdflatex --enable-write18 --extra-mem-bot=10000000 --synctex=1 <filename>
You may replace 10000000
by another ridiculous high number.
As was commented by @coatless, you may have to add --extra-mem-top=10000000
for other document types than my test example. The MiKTeX manual contains the following explanations:
--extra-mem-bot=n
: Set the extra size (in memory words) for large data structures like boxes, glue, breakpoints, et al. Relevant only after the memory dump file has been read.--extra-mem-top=n
: Set the extra size (in memory words) for chars, tokens, et al. Relevant only after the memory dump file has been read.
For illustration some example log entries from a test document:
Failing example without the extra memory:
21229 strings out of 493921
360228 string characters out of 3152094
3000000 words of memory out of 3000000
24030 multiletter control sequences out of 15000+200000
49729 words of font info for 45 fonts, out of 3000000 for 9000
841 hyphenation exceptions out of 8191
Working example with --extra-mem-bot=10000000
:
23652 strings out of 493921
401787 string characters out of 3152094
10571134 words of memory out of 13000000
24308 multiletter control sequences out of 15000+200000
49729 words of font info for 45 fonts, out of 3000000 for 9000
841 hyphenation exceptions out of 8191
Working example with --extra-mem-bot=100000000
:
23652 strings out of 493921
401787 string characters out of 3152094
100571134 words of memory out of 103000000
24308 multiletter control sequences out of 15000+200000
49729 words of font info for 45 fonts, out of 3000000 for 9000
841 hyphenation exceptions out of 8191
I guess that my example in truth needed 571134
words of memory (and the the rest is eaten up for fun).
Due to AlexG's comment, the memory size has been a constant large value for recent versions of TeX Live. It seems you don't need to extend this.
In older TeX Live, you can modify /some/path/to/texlive/some/subpath/web2c/texmf.cnf
, which can be found by typing on the terminal:
kpsewhich -a texmf.cnf
Then modify the memory size by including, e.g. :
main_memory = 3000000
(See comments in texmf.cnf
file for more details.)
Then run the following command as root to recreate the format files:
fmtutil-sys --all