Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
RMagick, migrate to ImageMagick 7 #RubyKaigi #R...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Watson
April 18, 2019
Programming
10k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RMagick, migrate to ImageMagick 7 #RubyKaigi #RubyKaigi2019
Watson
April 18, 2019
More Decks by Watson
See All by Watson
クラウドネイティブ時代に 進化し続けるFluentd
watson
0
36
Magick
watson
0
12k
Improve JSON Performance
watson
2
1.1k
fastlane 奮闘記
watson
0
100
How to optimize Ruby internal.
watson
3
3.1k
iOS、AndroidアプリをRubyで
watson
1
520
RubyMotion 2.0
watson
6
2.9k
Differences CRuby/MacRuby/RubyMotion
watson
5
5.8k
Other Decks in Programming
See All in Programming
Agents on Rails - Rails at Scale 2026
irinanazarova
0
520
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
320
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
360
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
310
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
260
速習iPhone Duo対応
yuukiw00w
2
970
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
160
golang-bob.pdf
iwatsukayura
0
110
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
21
21k
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
350
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
130
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
130
Featured
See All Featured
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
350
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Facilitating Awesome Meetings
lara
57
7.2k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Speed Design
sergeychernyshev
33
2.1k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
A Soul's Torment
seathinner
8
3.7k
Producing Creativity
orderedlist
PRO
348
41k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Exploring anti-patterns in Rails
aemeredith
4
530
Music & Morning Musume
bryan
48
7.4k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
66k
Transcript
RMagick, migrate to ImageMagick 7 Shizuo Fujita
self.inspect • @watson1978 • Ubiregi, Inc • Ruby committer •
RMagick maintainer
What's RMagick
"RMagick is an interface between the Ruby programming language and
the ImageMagick image processing library."
Active members ˏmockdeep ˏwatson1978 ˏdlemstra
My Motivation
I want to use Ruby ... •Web programming
I want to use Ruby ... •Web programming •iOS programming
I want to use Ruby ... •Web programming •iOS programming
•Image processing
I want to use Ruby ... •Web programming •iOS programming
•Image processing •Machine learning, etc
I want to use Ruby ... •Web programming •iOS programming
•Image processing •Machine learning, etc To meet crazy great people at Ruby World
Current Status of RMagick
None
Fixed major problems since v2.16.0 •Set up •Memory leaks •SEGVs
Set up problems
Set up problems •macOS (Homebrew) •Windows
macOS (Homebrew)
macOS (Homebrew)
Windows •Ruby has some environments • MingW • MSWin •
Cygwin • Windows Subsystem for Linux
Windows •Ruby has some environments • MingW • MSWin •
Cygwin • Windows Subsystem for Linux
MingW...?
Set up : MingW
Solution https://github.com/oneclick/rubyinstaller2/wiki/For-gem-developers
MingW works
MSWin...?
Set up : MSWin
MSWin supported...? Looks like MSWin supporting code...
Not supported... Why !? For MSWin
MSWin works well
Memory leak
Fixed many memory leaks 55 Closed
Case 1 VALUE Image_shear(VALUE self, VALUE x_shear, VALUE y_shear) {
Image *image, *new_image; ExceptionInfo *exception; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); new_image = ShearImage(image, NUM2DBL(x_shear), NUM2DBL(y_shear), exception); rm_check_exception(exception, new_image, DestroyOnError); (void) DestroyExceptionInfo(exception); rm_ensure_result(new_image); return rm_image_new(new_image); }
VALUE Image_shear(VALUE self, VALUE x_shear, VALUE y_shear) { Image *image,
*new_image; ExceptionInfo *exception; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); new_image = ShearImage(image, NUM2DBL(x_shear), NUM2DBL(y_shear), exception); rm_check_exception(exception, new_image, DestroyOnError); (void) DestroyExceptionInfo(exception); rm_ensure_result(new_image); return rm_image_new(new_image); } Case 1 Allocate memory
VALUE Image_shear(VALUE self, VALUE x_shear, VALUE y_shear) { Image *image,
*new_image; ExceptionInfo *exception; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); new_image = ShearImage(image, NUM2DBL(x_shear), NUM2DBL(y_shear), exception); rm_check_exception(exception, new_image, DestroyOnError); (void) DestroyExceptionInfo(exception); rm_ensure_result(new_image); return rm_image_new(new_image); } Case 1 Allocate memory Destroy memory
VALUE Image_shear(VALUE self, VALUE x_shear, VALUE y_shear) { Image *image,
*new_image; ExceptionInfo *exception; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); new_image = ShearImage(image, NUM2DBL(x_shear), NUM2DBL(y_shear), exception); rm_check_exception(exception, new_image, DestroyOnError); (void) DestroyExceptionInfo(exception); rm_ensure_result(new_image); return rm_image_new(new_image); } Case 1 Allocate memory Destroy memory Raise exception with unexpected value
VALUE Image_shear(VALUE self, VALUE x_shear, VALUE y_shear) { Image *image,
*new_image; ExceptionInfo *exception; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); new_image = ShearImage(image, NUM2DBL(x_shear), NUM2DBL(y_shear), exception); rm_check_exception(exception, new_image, DestroyOnError); (void) DestroyExceptionInfo(exception); rm_ensure_result(new_image); return rm_image_new(new_image); } Case 1 Allocate memory Destroy memory Raise exception with unexpected value Unreachable by exception
Case 1: Exception causes Memory Leak image = Magick::Image.read('sample.png').first begin
image.shear('x', 'y') rescue end
Case 2 static VALUE has_attribute(VALUE self, MagickBooleanType....[snip]) { Image *image;
ExceptionInfo *exception; MagickBooleanType r; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); r = (attr_test)(image, exception); CHECK_EXCEPTION() return r ? Qtrue : Qfalse; }
static VALUE has_attribute(VALUE self, MagickBooleanType....[snip]) { Image *image; ExceptionInfo *exception;
MagickBooleanType r; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); r = (attr_test)(image, exception); CHECK_EXCEPTION() return r ? Qtrue : Qfalse; } Case 2 Allocate memory
static VALUE has_attribute(VALUE self, MagickBooleanType....[snip]) { Image *image; ExceptionInfo *exception;
MagickBooleanType r; image = rm_check_destroyed(self); exception = AcquireExceptionInfo(); r = (attr_test)(image, exception); CHECK_EXCEPTION() return r ? Qtrue : Qfalse; } Case 2 Allocate memory Missing destroy
Case 2: Missing destroy lead to Memory Leak image =
Magick::Image.read('sample.png').first image.gray?
Case 3 Unnecessary clone API returns NEW image in allocated
memory
Case 3: Memory Leak by incorrect API usage image =
Magick::Image.read('sample.png').first image.sharpen_channel
Case 4
Case 4 Found memory leak in ImageMagick
Case 4
Case 4: Huge software has Memory Leak
How to detect memory leak
Profiler tool
Profiler tool Memory leak detected
Profiler tool
Profiler tool... •Detects at executed code only •unit-test •RSpec •Needs
better coverage...
Code reading... •To find same pattern that profiler detects
SEGV
Closed 5 SEGVs 4 Fixed 1 Workaround
Workaround Case Help wanted
Workaround Case •Call back image processing progress to Ruby User's
Ruby code RMagick ImageMagick Callback
ruby_stack_length() shows 51119378542 = 47 GB • Invalid stack length
• GC running →SEGV
RMagick is better than ever.
Future...
ImageMagick 7 support
Preparing draft code... now
Plan 1: Split RMagick ver 4.x RMagick ver 3.x ver
3.0 ver 3.1 ver 2.16.1 ImageMagick 7 ImageMagick 6
Plan 2 : Mix both ImageMagick 7 ImageMagick 7 ImageMagick
6 Using many #if defined ...
Plan 3: Bundle both ImageMagick 7 ImageMagick 6
We welcome good ideas for the future
Announcement •RubyData Workshop (Tomorrow, 14:20 ~) •RubyKaigi 2019 Code Party
(Tomorrow, 19:00 ~)
Thank you