Bug Prestasi Emacs pada macOS Dijejaki kepada Peruntukan Memori Berlebihan dalam Gelung Acara GUI

Pasukan Komuniti BigGo
Bug Prestasi Emacs pada macOS Dijejaki kepada Peruntukan Memori Berlebihan dalam Gelung Acara GUI

Isu prestasi yang telah lama mengganggu pengguna Emacs pada macOS akhirnya berjaya dijejaki kepada punca asalnya. Bug ini menunjukkan penggunaan memori yang semakin meningkat secara beransur-ansur dan akhirnya menyebabkan sistem membeku, terutamanya menjejaskan pengguna dengan perkakasan yang lebih pantas dan paparan DPI tinggi. Selepas bertahun-tahun aduan dan percubaan nyahpepijat yang gagal, siasatan terperinci telah mendedahkan punca masalah terletak jauh di dalam pelaksanaan GUI khusus macOS.

Paradoks Prestasi: Mac yang Lebih Pantas Menjadikan Emacs Lebih Perlahan

Siasatan mendedahkan masalah yang berlawanan dengan intuisi di mana perkakasan Mac yang lebih berkuasa sebenarnya memburukkan prestasi Emacs. Isu ini berpunca daripada cara Emacs mengendalikan acara GUI melalui panggilan [NSApp run] dalam gelung acara utama. Setiap kali ini berlaku, ia mencipta konteks grafik yang lengkap dari awal - memulakan tetingkap, memuatkan fon dan glif, dan melukis bingkai - hanya untuk merobohkan semuanya milisaat kemudian apabila pemprosesan acara selesai.

Pada mesin yang lebih pantas, kitaran ini berlaku beribu-ribu atau bahkan berjuta-juta kali semasa operasi mudah seperti mengubah saiz tetingkap. Semakin pantas perkakasan dapat memproses acara, semakin banyak kitaran peruntukan dan penyahperuntukan berlaku. Paparan DPI tinggi memburukkan lagi masalah dengan memerlukan peruntukan memori yang lebih besar untuk permukaan rendering.

NSApp run: Panggilan API macOS yang memulakan gelung acara aplikasi utama, memproses semua acara sistem yang belum selesai sebelum mengembalikan kawalan kepada kod pemanggil.

Seni Bina Threading Emacs macOS:

  • Thread utama
  • Thread EventDispatch
  • Thread pengendali deskriptor fail
  • Pergantungan tinggi pada mekanisme penguncian
  • Pemprosesan gelung tak terhingga untuk pengendalian acara

Pengurusan Memori yang Salah

Penciptaan dan pemusnahan sumber GUI yang pantas mewujudkan kesan berantai isu pengurusan memori. Walaupun Emacs mengendalikan kebanyakan operasi pembersihan dengan cekap, beberapa peruntukan terlepas daripada kawalan. Item menu, glif fon, dan salinan keadaan bingkai terkumpul dalam memori kerana enjin teras Emacs tidak menjangkakan contoh hantu ini yang dicipta oleh lapisan GUI.

Memburukkan lagi keadaan, macOS mula menyimpan cache objek yang kerap diperuntukkan ini, menganggapnya sebagai data penting. Ini menolak kandungan Emacs sebenar - pembolehubah, hasil carian, dan data pengguna - lebih jauh dalam keutamaan memori. Komuniti telah membangunkan penyelesaian sementara, tetapi seni bina asas kekal bermasalah.

Kod Ujian Kebocoran Memori:

(dotimes (x 10000)
  (let ((frame (make-frame-command)))
    (sleep-for 0.01)
    (delete-frame frame)))

Potongan kod ini menunjukkan kebocoran memori dengan mencipta dan memadamkan bingkai secara pantas, menyebabkan penggunaan memori meningkat secara berterusan.

Komuniti Mencari Alternatif di Tengah Kekecewaan

Isu prestasi telah mendorong ramai pengguna Emacs lama untuk mempertimbangkan alternatif atau penyelesaian sementara. Sesetengahnya telah beralih kepada menjalankan Emacs secara eksklusif dalam mod terminal, mengorbankan ciri GUI untuk kestabilan dan prestasi. Yang lain meneroka editor yang berbeza sepenuhnya, dengan Helix dan NeoVim kerap disebut sebagai pengganti yang berpotensi.

Emacs jank pada macOS telah perlahan-lahan membunuh saya. Cukup sehinggakan, saya berfikir untuk beralih sepenuhnya selepas hampir sedekad menggunakan emacs.

Keadaan ini telah mewujudkan ekosistem yang berkembang pesat dengan binaan dan fork Emacs alternatif khusus untuk macOS, termasuk Emacs Doom, Homebrew Emacs-Plus, dan emacs-mac oleh Mitsuharu Yamamoto. Alternatif ini sering memberikan prestasi yang lebih baik tetapi memerlukan pengguna mengekalkan pemasangan yang berasingan.

Binaan Alternatif Emacs untuk macOS:

  • Emacs Doom
  • MacPorts Emacs
  • Homebrew Emacs-Plus
  • Mitsuharu Yamamoto's emacs-mac
  • Aquamacs
  • PGTK frontend (natif Wayland, berpotensi disesuaikan untuk macOS)

Penyelesaian Berpotensi di Ufuk

Perbincangan sedang berlangsung dalam komuniti pembangunan Emacs mengenai pembetulan yang berpotensi, walaupun penyelesaian tidak akan mudah. Pelaksanaan semasa menggunakan hanya tiga thread dan sangat bergantung pada mekanisme penguncian. Penyelesaian yang betul memerlukan perubahan seni bina yang ketara kepada pengendalian acara dan sokongan threading.

Satu pendekatan yang dicadangkan melibatkan pemindahan beransur-ansur kod khusus macOS kepada Swift, yang menawarkan pengurusan memori yang lebih baik, sokongan tak segerak terbina dalam, dan ciri keselamatan thread. Ini berpotensi menghapuskan mekanisme penguncian yang kompleks dan menyediakan pengendalian sumber yang lebih cekap, walaupun perubahan sedemikian akan mewakili usaha besar.

Siasatan ini menyerlahkan cabaran yang lebih luas yang dihadapi aplikasi merentas platform: mengimbangi tuntutan paradigma sistem pengendalian yang berbeza sambil mengekalkan fungsi dan prestasi yang konsisten merentas semua platform yang disokong.

Rujukan: Emacs: The MacOS Bug