Page MenuHomePhabricator

"Lua error: not enough memory" on certain en.wiktionary pages
Closed, InvalidPublic

Description

ISSUE:
Several users and I see "Lua error: not enough memory" in "water" when all its content is present, as in https://en.wiktionary.org/w/index.php?title=water&oldid=42726961 , and recently also in "man" https://en.wiktionary.org/w/index.php?title=man&oldid=42871191 . Errors persist despite efforts to simplify Lua-using templates in ways that do not reduce functionality.

The temporary workaround has been to split "water" onto two pages, and disable script support and transliteration of translations of "man"; this is undesirable because it reduces functionality. Many entries will one day be as complete as "water", so the issue will effect more pages if the causes are not addressed. (Indeed, in the last week another page developed an error.)

POSSIBLE SOLUTIONS:
We suspect Lua's garbage collection may have an issue: maybe individually not-intensive things, like individual templates, do not free up all their memory when they finish. If the issue is with Lua tasks not releasing memory when done, it would be ideal to improve that.

We also know some of our code is resource-intensive, so perhaps some errors could be solved if you could help us identify which pieces of code used on the above-linked revisions use the most memory, and how they could be streamlined without losing functionality (like automatic transliteration, etc).

Perhaps it would be possible to add "a function to create a 'cache' of language and script objects that can be used by multiple functions"; see explanation and rationale at https://en.wiktionary.org/wiki/Wiktionary:Grease_pit/2017/May#lsobjectcache .

Alternatively, perhaps it would be preferable to just raise the amount of memory that pages can use. (How would that affect mobile users?)

EXTRA DETAILS:
There is some randomness to the errors : I loaded https://en.wiktionary.org/w/index.php?title=water&oldid=42726961 and memory ran out in one place; I hard-refreshed and it ran out in another place. At the same time, there has consistently been no error in https://en.wiktionary.org/wiki/a or https://en.wiktionary.org/wiki/woman , even though "a" is larger than "man"; "a" and "woman" use more templates than "man"; and "woman" has ~2x as many translation templates (which are known to be resource-heavy and to contribute to errors) as "man".

Event Timeline

Urbanecm added a subscriber: Urbanecm.

@Framawiki Are you sure this is Wikimedia Site request? I think this is related to Scribunto more than being a site request.

Anomie added a subscriber: Anomie.

We suspect Lua's garbage collection may have an issue

"We suspect" isn't helpful. Provide actual test cases that illustrate that it's actually a problem in Scribunto rather than your module just using too much memory. A 194k page with a multitude of nested template invocations that happens to have errors isn't a test case.

I note if I edit that revision of your 'water' page and change all the uses of {{t}}, {{t+}}, {{t-check}}, {{t-image}}, {{t-needed}}, and {{t-simple}} to use the same language for the first parameter (in my test, I used 'de') without changing anything else at all, it mo longer produces errors. That also causes the page to load 90 fewer modules, mostly "Module:foo-translit". Your "garbage collection issue" might simply be that every one of those modules is cached so they don't have to be reparsed from scratch each time they're used.

Perhaps it would be possible to add "a function to create a 'cache' of language and script objects that can be used by multiple functions"; see explanation and rationale at https://en.wiktionary.org/wiki/Wiktionary:Grease_pit/2017/May#lsobjectcache .

It's not possible to create an mw.loadData with functions, since that would be an instance of T67258: Information can be passed between #invoke's (tracking).

The purpose of mw.loadData isn't to save memory, it's to save the time that would otherwise be required to reparse the data module every time.

Alternatively, perhaps it would be preferable to just raise the amount of memory that pages can use. (How would that affect mobile users?)

While raising the memory limit is possible, at some point in the future you'll probably wind up with an even-huger page that would exceed the new limit.

Another case from it.wikisource: https://it.wikisource.org/wiki/Ricordi_di_Parigi/Uno_sguardo_all%E2%80%99Esposizione

It pops out into a proofread ns0 pages with multiple calls to an it.wikisource module: Modulo:Wl

Using a test page with lots of identical calls to Modulo:Wl, really the "NewPP limit report" into source html tells "Lua memory usage: 50 MB/50 MB", t.i. Lua used really the whole amount of available memory.

Article wiktionary:si beginning from the section Slovak demonstrates multiple "Lua error: not enough memory".

It is affecting this page, from Vietnamese on: https://en.wiktionary.org/wiki/o

As noted by Anomie above, those reports "it affects this page" aren't much helpful. Those issues are very likely about a module written in an inefficient way, thus hitting the security memory limits. If that's right, it would be something that needs to be solved by on wiki developers who maintain the code.

It is possible (albeit unlikely) this is about an actual problem in Lua or the way we integrate it into our systems. However, in order to text that theory, a small test case page that produces the error would be required.

Unless I have misunderstood, Caoimhin has provided a link to a suitable test page that reproduces this fault, as have others - consistently and across platforms in my experience. This should allow someone to narrow down where the fault is. But it is not possible to provide the small test case page that you request, because it does not happen on small pages. It happens towards the end of exceptionally long pages. That is why you will find it for any really common word (such as a or o) in languages that are near the end alphabetically, such as Vietnamese and Welsh.

We do not need more "happens also on page..." test cases.
We welcome test cases though that illustrate that it's actually a problem in Scribunto (!). And not that local modules use too much memory.

This should allow someone to narrow down where the fault is.

https://en.wiktionary.org/wiki/o loads 288 templates and 163 modules. That takes memory. :)

The problem seems to be that the version of Lua used by Scribunto does not run the garbage collector when a memory allocation fails, so memory is not reclaimed when it is needed most. I would consider that a bug of the the implementation. With that behaviour it's hard to tell if we're really out of memory, or if we're just out of luck, because the GC didn't run in time.

The problem seems to be that the version of Lua used by Scribunto does not run the garbage collector when a memory allocation fails, so memory is not reclaimed when it is needed most. I would consider that a bug of the the implementation. With that behaviour it's hard to tell if we're really out of memory, or if we're just out of luck, because the GC didn't run in time.

Can you tell us how did you reach to that conclusion?

The problem seems to be that the version of Lua used by Scribunto does not run the garbage collector when a memory allocation fails, so memory is not reclaimed when it is needed most. I would consider that a bug of the the implementation. With that behaviour it's hard to tell if we're really out of memory, or if we're just out of luck, because the GC didn't run in time.

Can you tell us how did you reach to that conclusion?

Lua 5.2 includes an EmergencyGarbageCollector, which means that the GC always gets a chance to run when a memory allocation fails.

There is no such thing on Lua 5.1, which Scribunto is based on, so it won't try to free memory when needed. This also leads to unpredictable behaviour (pages fail, then work after a reload).