A QuickLook plugin on macOS 10.14 has several constraints to satisfy. If one of the limits is exceeded, the plugin will immediately be killed and no preview will be visible. Having such restrictions makes sense but they appear to be undocumented. This article addresses the lack of information about these constraints.

  • Easily preview Mermaid diagrams
  • Live update when editing in your preferred editor
  • Capture screenshots with customizable margins
  • Create PNG from the Terminal
  • Free download on the Mac App Store
MarkChart

In a previous article, I unveiled a QuickLook plugin to visualize .car files (compiled Asset Catalogs). For this plugin, some of the limits could have been reached with car files containing a lot of assets or on slow machines. Since having a partial preview is much better than having no preview at all, I added in this plugin code to detect when the plugin gets close to the limits. When this occurs, the assets won’t be processed anymore but only counted. Here is a screenshot of the QuickLook preview when this happens:

On macOS 10.14, the QuickLook daemon applies 3 kinds of restrictions on the plugins:

  • maximum execution duration
  • maximum memory usage
  • maximum number of open file descriptors.

We can see the hardcoded values for these limits in the QuickLook framework:

Timeout

The preview and thumbnail should be generated in a fixed amount of time:

  • 30s (QLMaxPreviewTimeOut) for previews
  • 20s (QLMaxThumbnailTimeOut) for thumbnails

If the plugin takes more than this duration to generate the preview/thumbnail, the plugin is killed, meaning that no preview will be visible.

For the QLCARFiles QuickLook plugin, the 30s timeout could possibly be reached for large car files or on slow machines. To prevent the plugin to be killed - meaning no preview at all - I stop processing the assets after 20s. You would only see the preview for the first assets and a tile indicating how many assets were not processed.

Memory Usage

The plugin is killed right away if it uses more than 120MB of memory (2 * QLMemoryUsedCritical). If more than 80MB of memory (2 * QLMemoryUsedUsage) is used, the plugin might be killed too. For these cases, you would see a log similar to:

Using too much memory (147 MB), hit critical threshold (120 MB), exiting immediately to clean up.

To prevent the QLCARFiles QuickLook plugin to be killed, I stop processing the assets if the memory usage reaches 70 MB. I used in the plugin some code similar to what Apple does:

BOOL IsCriticalMemoryUsage()
{
	malloc_statistics_t stats = { 0 };
	malloc_zone_statistics(NULL, &stats);
	
	if(stats.size_in_use > MAX_MEMORY_LIMIT)
	{
		os_log(OS_LOG_DEFAULT, "Using too much memory: %0.1f MB", ((double)stats.size_in_use) / (1024.0 * 1024.0));
		return YES;
	}
	
	return NO;
}

Open File Descriptors

The number of open file descriptors is limited. If you exceed the value getdtablesize() - which is typically 256 - you will see the following log in the Console:

Using too many open descriptors (256/256), exiting immediately to clean-up

In the QLCARFiles QuickLook plugin, this limit should never be reached because only the car file is open.

It is worth mentioning that you could bypass this restriction by modifying the RLIMIT_NOFILE value, for example by allowing up to 1024 open file descriptors:

struct rlimit lim = {1024, 1024};
if (setrlimit(RLIMIT_NOFILE, &lim) == -1)
{
	os_log(OS_LOG_DEFAULT, "Could not set RLIMIT_NOFILE to %lld:%lld", lim.rlim_cur, lim.rlim_max);
}