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
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
35
Magick
watson
0
12k
Improve JSON Performance
watson
2
1.1k
fastlane 奮闘記
watson
0
99
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
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
0
1.5k
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
360
Jetpack Compose メカニズム
skydoves
0
450
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
3
360
速習iPhone Duo対応
yuukiw00w
1
660
iOSDC2026登壇資料.pdf
riofujimon
0
170
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
250
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
160
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
220
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
120
App Intentsのビルドプロセスを支える技術
kntkymt
0
400
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
350
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.6k
Six Lessons from altMBA
skipperchong
29
4.5k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Faster Mobile Websites
deanohume
310
32k
Test your architecture with Archunit
thirion
2
2.4k
A Tale of Four Properties
chriscoyier
163
24k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
700
A better future with KSS
kneath
240
18k
Done Done
chrislema
186
16k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
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