CopyQ icon indicating copy to clipboard operation
CopyQ copied to clipboard

Massive leaking on macOS

Open hmijail opened this issue 7 years ago • 11 comments

I've noticed that after some hours, CopyQ's process grows to be the one using the most memory in the system.

A quick run with macOS' Instruments shows that all of the leaks come from a stack trace like this, caused just by copying and pasting (no script usage):

    0 libsystem_malloc.dylib malloc_zone_malloc
--- 9 frames omitted ---
  10 SkyLight CGSPropertyListCreateWithSerializedData
  11 SkyLight createPlistFromData :209700
  12 SkyLight SLWindowListCopyWindowInfo :209700
  13 copyq MacPlatformWindow::MacPlatformWindow(NSRunningApplication*)
--- 27 frames omitted ---
  41 libdyld.dylib start

However, the collapsed frames hide some variation between leaks. The most frequent leak expands like this:

   0 libsystem_malloc.dylib malloc_zone_malloc
   1 CoreFoundation _CFRuntimeCreateInstance
   2 CoreFoundation CFStringCreateMutable
   3 CoreFoundation CFStringCreateMutableCopy
   4 CoreFoundation __CFBinaryPlistCreateObjectFiltered
   5 CoreFoundation __CFBinaryPlistCreateObjectFiltered
   6 CoreFoundation __CFBinaryPlistCreateObjectFiltered
   7 CoreFoundation __CFTryParseBinaryPlist
   8 CoreFoundation _CFPropertyListCreateWithData
   9 CoreFoundation CFPropertyListCreateWithData
  10 SkyLight CGSPropertyListCreateWithSerializedData
  11 SkyLight createPlistFromData :209700
  12 SkyLight SLWindowListCopyWindowInfo :209700
  13 copyq MacPlatformWindow::MacPlatformWindow(NSRunningApplication*)
  14 copyq MacPlatform::getCurrentWindow()
  15 copyq ScriptableProxy::pasteToCurrentWindow()
  16 copyq 0x105a0a330
  17 QtCore QObject::event(QEvent*)
  18 QtWidgets QWidget::event(QEvent*)
  19 QtWidgets QMainWindow::event(QEvent*)
  20 QtWidgets QApplicationPrivate::notify_helper(QObject*, QEvent*)
  21 QtWidgets QApplication::notify(QObject*, QEvent*)
  22 copyq 0x105b2ed60
  23 QtCore QCoreApplication::notifyInternal2(QObject*, QEvent*)
  24 QtCore QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*)
  25 libqcocoa.dylib 0x10abe6560
  26 libqcocoa.dylib 0x10abe6ec0
  27 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
  28 CoreFoundation __CFRunLoopDoSources0
  29 CoreFoundation __CFRunLoopRun
  30 CoreFoundation CFRunLoopRunSpecific
  31 HIToolbox RunCurrentEventLoopInMode
  32 HIToolbox ReceiveNextEventCommon
  33 HIToolbox _BlockUntilNextEventMatchingListInModeWithFilter
  34 AppKit _DPSNextEvent
  35 AppKit -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]
  36 AppKit -[NSApplication run]
  37 libqcocoa.dylib 0x10abe52c0
  38 QtCore QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)
  39 QtCore QCoreApplication::exec()
  40 copyq main
  41 libdyld.dylib start

To try to get better details, I have tried running CopyQ under Valgrind, but it's still too broken in macOS 10.12.

I have also tried building CopyQ with clang's sanitizers, but even the plain build instructions for macOS do not work. They fail like this:

14:~/repos/CopyQ$ /usr/local/opt/qt5/bin/qmake
Info: creating stash file /Users/mija/repos/CopyQ/.qmake.stash
Info: creating cache file /Users/mija/repos/CopyQ/.qmake.cache
15:~/repos/CopyQ$ make copyq.app
make: *** No rule to make target `copyq.app'.  Stop.

I am not versed on C++ nor Qt and its build system so I'm stopping here.

hmijail avatar Aug 28 '17 10:08 hmijail

Forgot to add: this is in Copyq 3.0.3 installed with Homebrew on macOS 10.12.6.

hmijail avatar Aug 28 '17 10:08 hmijail

Thanks for the detailed report.

Culprit could be this call to CGWindowListCreateDescriptionFromArray(). The word Create in the function name suggest that it allocates memory even though documentation doesn't mention this. (So CFRelease(array) should be called.)

Cannot test it right now but I think the memory leaks if you run following command in terminal.

copyq 'for (i=0;i<1000;++i) currentWindowTitle()'

hluk avatar Aug 28 '17 12:08 hluk

And I think there is same problem with CGWindowListCopyWindowInfo() calls. I should review the mac code.

hluk avatar Aug 28 '17 12:08 hluk

That terminal command seems to cause about 200MB in leaks, and the collapsed stack trace is the same I reported initially.

hmijail avatar Aug 28 '17 12:08 hmijail

I'm trying to fix this in osx-leaks branch. Memory management in Objective C sucks.

I managed to decrease the memory consumption for the test command I mentioned in my previous comment.

Another case where the memory leaks is with following command.

copyq 'for (x=config("autostart"),i=0;i<50;++i) {x=!x;config("autostart",x);}'

Unfortunately, I'm not very familiar with Objective C so any help is welcome.

hluk avatar Aug 28 '17 18:08 hluk

I merged the fix to master branch. Keeping this open since there are still some leaks.

hluk avatar Sep 02 '17 06:09 hluk

yes I can confirm :(

cpatti97100 avatar Jun 05 '18 15:06 cpatti97100

yes I can confirm :(

@clivend You mean the leaks? With version 3.4.0? Can you provide more info?

I won't be able to fix this in near future - currently, I don't have access to any OS X system. I really need someone to help me with these mac issues.

hluk avatar Jun 05 '18 16:06 hluk

@hluk sure! next time it happens I will report everything

how to check installed version on mac? what should the normal ram usage be for 200 items in history and 20 shown?

cpatti97100 avatar Jun 06 '18 15:06 cpatti97100

@clivend Check version with copyq --version.

Memory usage depends on many factors. For me it's about 20MiB at start (depends a lot on amount of items in clipboard tab which will probably be loaded at start).

hluk avatar Jun 06 '18 16:06 hluk

Should this old issue be closed? We have a newer issue for macOS with #1928.

reagle avatar Jun 07 '22 21:06 reagle