Download free for 30 days
Sign in
Upload
Language (EN)
Support
Business
Mobile
Social Media
Marketing
Technology
Art & Photos
Career
Design
Education
Presentations & Public Speaking
Government & Nonprofit
Healthcare
Internet
Law
Leadership & Management
Automotive
Engineering
Software
Recruiting & HR
Retail
Sales
Services
Science
Small Business & Entrepreneurship
Food
Environment
Economy & Finance
Data & Analytics
Investor Relations
Sports
Spiritual
News & Politics
Travel
Self Improvement
Real Estate
Entertainment & Humor
Health & Medicine
Devices & Hardware
Lifestyle
Change Language
Language
English
Español
Português
Français
Deutsche
Cancel
Save
Submit search
EN
Uploaded by
JustSystems Corporation
8,487 views
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
2017/11/18 JJUG CCC 2017 Fallでの発表資料です。 #jjug_ccc #ccc_g5
Software
◦
Read more
6
Save
Share
Embed
Embed presentation
1
/ 28
2
/ 28
3
/ 28
4
/ 28
Most read
5
/ 28
6
/ 28
7
/ 28
8
/ 28
9
/ 28
10
/ 28
11
/ 28
12
/ 28
13
/ 28
14
/ 28
15
/ 28
16
/ 28
17
/ 28
18
/ 28
19
/ 28
20
/ 28
21
/ 28
22
/ 28
23
/ 28
24
/ 28
25
/ 28
26
/ 28
27
/ 28
28
/ 28
More Related Content
PDF
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021
by
Preferred Networks
PDF
人生がときめくAPIテスト自動化 with Karate
by
Takanori Suzuki
PPTX
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
by
Ohyama Masanori
PDF
GoによるWebアプリ開発のキホン
by
Akihiko Horiuchi
PDF
Apache Airflow入門 (マーケティングデータ分析基盤技術勉強会)
by
Takeshi Mikami
PDF
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...
by
Insight Technology, Inc.
PDF
DockerとPodmanの比較
by
Akihiro Suda
PDF
MapReduce入門
by
Satoshi Noto
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021
by
Preferred Networks
人生がときめくAPIテスト自動化 with Karate
by
Takanori Suzuki
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
by
Ohyama Masanori
GoによるWebアプリ開発のキホン
by
Akihiko Horiuchi
Apache Airflow入門 (マーケティングデータ分析基盤技術勉強会)
by
Takeshi Mikami
[C33] 24時間365日「本当に」止まらないデータベースシステムの導入 ~AlwaysOn+Qシステムで完全無停止運用~ by Nobuyuki Sa...
by
Insight Technology, Inc.
DockerとPodmanの比較
by
Akihiro Suda
MapReduce入門
by
Satoshi Noto
What's hot
PDF
PostgreSQL 15の新機能を徹底解説
by
Masahiko Sawada
PDF
PostgreSQL Unconference #29 Unicode IVS
by
Noriyoshi Shinoda
PPTX
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
by
NTT DATA Technology & Innovation
PDF
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
by
NTT DATA Technology & Innovation
PDF
AWSのログ管理ベストプラクティス
by
Akihiro Kuwano
PDF
PlaySQLAlchemy: SQLAlchemy入門
by
泰 増田
PDF
マルチテナントのアプリケーション実装〜実践編〜
by
Yoshiki Nakagawa
PDF
PostgreSQL - C言語によるユーザ定義関数の作り方
by
Satoshi Nagayasu
PDF
nginx入門
by
Takashi Takizawa
PDF
コンテナ未経験新人が学ぶコンテナ技術入門
by
Kohei Tokunaga
PPTX
MongoDBが遅いときの切り分け方法
by
Tetsutaro Watanabe
PDF
HA環境構築のベスト・プラクティス
by
EnterpriseDB
PDF
40分でわかるHadoop徹底入門 (Cloudera World Tokyo 2014 講演資料)
by
hamaken
PDF
Where狙いのキー、order by狙いのキー
by
yoku0825
PPTX
これがCassandra
by
Takehiro Torigaki
PDF
ゼロからはじめるKVM超入門
by
VirtualTech Japan Inc.
PDF
JJUG CCC 2018 Spring - I-7 (俺が)はじめての Netty
by
Shinya Mochida
PDF
関数型プログラミングのデザインパターンひとめぐり
by
Kazuyuki TAKASE
PDF
怖くないSpring Bootのオートコンフィグレーション
by
土岐 孝平
PDF
Apache Kafka 0.11 の Exactly Once Semantics
by
Yoshiyasu SAEKI
PostgreSQL 15の新機能を徹底解説
by
Masahiko Sawada
PostgreSQL Unconference #29 Unicode IVS
by
Noriyoshi Shinoda
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
by
NTT DATA Technology & Innovation
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
by
NTT DATA Technology & Innovation
AWSのログ管理ベストプラクティス
by
Akihiro Kuwano
PlaySQLAlchemy: SQLAlchemy入門
by
泰 増田
マルチテナントのアプリケーション実装〜実践編〜
by
Yoshiki Nakagawa
PostgreSQL - C言語によるユーザ定義関数の作り方
by
Satoshi Nagayasu
nginx入門
by
Takashi Takizawa
コンテナ未経験新人が学ぶコンテナ技術入門
by
Kohei Tokunaga
MongoDBが遅いときの切り分け方法
by
Tetsutaro Watanabe
HA環境構築のベスト・プラクティス
by
EnterpriseDB
40分でわかるHadoop徹底入門 (Cloudera World Tokyo 2014 講演資料)
by
hamaken
Where狙いのキー、order by狙いのキー
by
yoku0825
これがCassandra
by
Takehiro Torigaki
ゼロからはじめるKVM超入門
by
VirtualTech Japan Inc.
JJUG CCC 2018 Spring - I-7 (俺が)はじめての Netty
by
Shinya Mochida
関数型プログラミングのデザインパターンひとめぐり
by
Kazuyuki TAKASE
怖くないSpring Bootのオートコンフィグレーション
by
土岐 孝平
Apache Kafka 0.11 の Exactly Once Semantics
by
Yoshiyasu SAEKI
Similar to 「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
PDF
Javaはどのように動くのか~スライドでわかるJVMの仕組み
by
Chihiro Ito
PPTX
第六回渋谷Java Java8のJVM監視を考える
by
chonaso
PPTX
省メモリーに関するデザインパターン 2011.04.18
by
Minoru Chikamune
PDF
インメモリーで超高速処理を実現する場合のカギ
by
Masaki Yamakawa
PDF
10のJava9で変わるJava8の嫌なとこ!
by
bitter_fox
PPT
Javaメモリ勉強会
by
Tetsuya Yoshida
PPTX
Jdk9で変更になる(かも知れない)jvmオプションの標準設定
by
Kazuyuki Nakamura
PDF
みんな大好きJava gc入門 【前編】
by
kouzirou tenkubashi
PDF
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
by
PE-BANK
PDF
新版 OutOfMemoryErrorを知る
by
Masahiro Hidaka
PDF
Versatil Javaチューニング
by
Kenji Kazumura
PDF
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
by
なおき きしだ
PDF
[豆ナイト]Java small object programming
by
Yuichi Hasegawa
PDF
函館IKA Eclipse活用術
by
Masahiro Wakame
PDF
これからのコンピューティングとJava(Hacker Tackle)
by
なおき きしだ
PDF
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
by
なおき きしだ
KEY
関ジャバ JavaOne Tokyo 2012報告会
by
Koichi Sakata
ODP
Object oriented-01
by
Osam Tmu
PDF
夏だからJava再入門
by
Katsumi Honda
PDF
【Unity道場スペシャル 2018京都】プロなら当然!プログラミング技能解説
by
Unity Technologies Japan K.K.
Javaはどのように動くのか~スライドでわかるJVMの仕組み
by
Chihiro Ito
第六回渋谷Java Java8のJVM監視を考える
by
chonaso
省メモリーに関するデザインパターン 2011.04.18
by
Minoru Chikamune
インメモリーで超高速処理を実現する場合のカギ
by
Masaki Yamakawa
10のJava9で変わるJava8の嫌なとこ!
by
bitter_fox
Javaメモリ勉強会
by
Tetsuya Yoshida
Jdk9で変更になる(かも知れない)jvmオプションの標準設定
by
Kazuyuki Nakamura
みんな大好きJava gc入門 【前編】
by
kouzirou tenkubashi
Javaヂカラ #Java最新動向 -Java 11 の新機能やOracle Code One 2018 発の最新技術トレンドを一気にキャッチアップ-
by
PE-BANK
新版 OutOfMemoryErrorを知る
by
Masahiro Hidaka
Versatil Javaチューニング
by
Kenji Kazumura
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
by
なおき きしだ
[豆ナイト]Java small object programming
by
Yuichi Hasegawa
函館IKA Eclipse活用術
by
Masahiro Wakame
これからのコンピューティングとJava(Hacker Tackle)
by
なおき きしだ
これからのコンピューティングの変化とJava-JJUG CCC 2015 Fall
by
なおき きしだ
関ジャバ JavaOne Tokyo 2012報告会
by
Koichi Sakata
Object oriented-01
by
Osam Tmu
夏だからJava再入門
by
Katsumi Honda
【Unity道場スペシャル 2018京都】プロなら当然!プログラミング技能解説
by
Unity Technologies Japan K.K.
More from JustSystems Corporation
PDF
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
by
JustSystems Corporation
PDF
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
by
JustSystems Corporation
PDF
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
by
JustSystems Corporation
PDF
AWS運用における最適パターンの徹底活用
by
JustSystems Corporation
PDF
ピュアJavaだと思った?残念androidでした~いつからAndroidをJavaだと錯覚していた?~
by
JustSystems Corporation
PPTX
Selenium WebDriver + python で E2Eテスト自動化
by
JustSystems Corporation
PPTX
JavaでインメモリSQLエンジンを作ってみた
by
JustSystems Corporation
PDF
最新のJava言語仕様で見るモジュールシステム #jjug
by
JustSystems Corporation
PDF
「技術内閣制度」〜2年間やってきて得られた事とこれから〜 #devsumi
by
JustSystems Corporation
PDF
インパス! あのこれダメッス! ~Javaコードレビューの指摘ポイント10選~
by
JustSystems Corporation
PPTX
ジャストシステムのDevOps実例 今後の取り組み
by
JustSystems Corporation
PDF
JustTechTalk#10windowsアプリでのテスト自動化事例
by
JustSystems Corporation
PPTX
TypeScriptの大規模開発への適用
by
JustSystems Corporation
PDF
CSSレイアウトでなぜ失敗するか?
by
JustSystems Corporation
PDF
JustTechTalk#11_スマイルゼミ顧客満足度への貢献
by
JustSystems Corporation
PPTX
Kotlin is charming; The reasons Java engineers should start Kotlin.
by
JustSystems Corporation
PDF
JustTechTalk#10 React開発における自動テスト実践
by
JustSystems Corporation
PDF
UX実現に向けた社内の取り組みについて-訴求ファーストによる商品開発-
by
JustSystems Corporation
PDF
現役23名のPM:タイプ別マネジメントパターン
by
JustSystems Corporation
PDF
事業に貢献する商品開発と その成長の仕組み作り ~これからのエンジニアに必要とされるスキルとは~
by
JustSystems Corporation
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
by
JustSystems Corporation
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
by
JustSystems Corporation
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
by
JustSystems Corporation
AWS運用における最適パターンの徹底活用
by
JustSystems Corporation
ピュアJavaだと思った?残念androidでした~いつからAndroidをJavaだと錯覚していた?~
by
JustSystems Corporation
Selenium WebDriver + python で E2Eテスト自動化
by
JustSystems Corporation
JavaでインメモリSQLエンジンを作ってみた
by
JustSystems Corporation
最新のJava言語仕様で見るモジュールシステム #jjug
by
JustSystems Corporation
「技術内閣制度」〜2年間やってきて得られた事とこれから〜 #devsumi
by
JustSystems Corporation
インパス! あのこれダメッス! ~Javaコードレビューの指摘ポイント10選~
by
JustSystems Corporation
ジャストシステムのDevOps実例 今後の取り組み
by
JustSystems Corporation
JustTechTalk#10windowsアプリでのテスト自動化事例
by
JustSystems Corporation
TypeScriptの大規模開発への適用
by
JustSystems Corporation
CSSレイアウトでなぜ失敗するか?
by
JustSystems Corporation
JustTechTalk#11_スマイルゼミ顧客満足度への貢献
by
JustSystems Corporation
Kotlin is charming; The reasons Java engineers should start Kotlin.
by
JustSystems Corporation
JustTechTalk#10 React開発における自動テスト実践
by
JustSystems Corporation
UX実現に向けた社内の取り組みについて-訴求ファーストによる商品開発-
by
JustSystems Corporation
現役23名のPM:タイプ別マネジメントパターン
by
JustSystems Corporation
事業に貢献する商品開発と その成長の仕組み作り ~これからのエンジニアに必要とされるスキルとは~
by
JustSystems Corporation
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
1.
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~ JJUG CCC 2017
Fall 2017/11/18 #jjug_ccc #ccc_g5 1
2.
JUSTSYSTEMS 自己紹介 • 株式会社ジャストシステム 猪鼻哲也 •
担当商品履歴 • MS-DOS上のOffice系アプリケーション • Windows上のOffice系アプリケーション • Windows上の情報活用系アプリケーション • ストレージ系インターネットサービス • オンプレミス文書管理系サーバ • オンプレミス情報活用系サーバ • ... • Java歴18年 • 低レイヤーの実装まわりが好き 2
3.
JUSTSYSTEMS 本日の内容 • Javaオブジェクトの構造 • メモリ使用量の削減 •
ライブラリの利用 • まとめ • 付録 3
4.
JUSTSYSTEMS Java進化の歴史 • 機能面はもちろんのこと、性能面の進化が普及できた 大きな要因(特にサーバーサイド) • 速度はJIT/HotSpotの進化で商用レベルに(JDK1.3~) •
メモリについては、H/Wの進化と64bit VMにより、over 2GB の大容量が実現可能に • エンタープライズ検索やインメモリDBによる集計・分析といっ た、昔では考えられなかった機能も実現 <弊社製品例> https://www.justsystems.com/jp/products/cbes https://www.justsystems.com/jp/products/actionista/ 4
5.
JUSTSYSTEMS メモリ不足はサービス安定運用の大敵 • メモリ使用量やリークに注意しないとSTW(Stop the world)やOOM(OutOfMemoryError)が発生 •
リークしてなくても-Xmxの8~9割程度使ってしまうと メモリ確保/GCの負荷上昇でスループットが落ちてく る(経験上) • スループット低下やサービスダウン→緊急の対応が必要 最初からメモリ使用量を抑えておくに越したことはない 5
6.
JUSTSYSTEMS Javaオブジェクトの構造 6
7.
JUSTSYSTEMS Javaオブジェクトの構造 /* フィールドのオフセットをsun.misc.Unsafe.objectFieldOffset()で取得すると、 管理用データのサイズを反映した値が返る */ class
A { public int a; }; ... Unsafe unsafe = ...(略); // sun.misc.Unsafeの”theUnsafe”をリフレクションで取得 Field aField = A.class.getDeclaredField(“a”); // class Aのフィールドaを取得 long offset = unsafe.objectFieldOffset(aField); // フィールドaのオフセットを取得 // 32bitVMで8 (4 + 4) // 64bitVM -XX:+UseCompressedOopsで12 (8 + 4) // 64bitVM -XX:–UseCompressedOops(または-Xmx32g以上)で16 (8 + 8) Javaソースで定義 したフィールド... (8バイトアラインメント) _mark _klass • 管理用のデータ領域を先頭に持つ • _mark → オブジェクトの状態 • 32bit VMの場合4バイト、64bit VMで8バイト • _klass →クラスデータへの参照 • 32bit VMの場合4バイト、64bit VMで8バイト • 64bitでもCompressedOops(オブジェクト参照を圧縮す る仕組み)が有効な場合は4バイト ど の オ ブ ジ ェ ク ト も 必 ず 持 っ て い る 領 域 7
8.
JUSTSYSTEMS 基本型とラッパークラス • ラッパークラスのオブジェクトは管理領域+保持している基 本型サイズ+パディングのメモリを消費 基本型とそのサイズ(バイト) 対応するラッパークラスとそのメモリ使用量(バイト) 型名
サイズ クラス名 32bit JVM 64bit JVM 32GB未満 64bit JVM 32GB以上 boolean 1 Boolean 16 16 24 byte 1 Byte 16 16 24 char 2 Character 16 16 24 short 2 Short 16 16 24 int 4 Integer 16 16 24 float 4 Float 16 16 24 long 8 Long 16 24 24 double 8 Double 16 24 24 8 boolean Boolean(32bit JVM) Boolean(64bit JVM<32GB) Boolean(64bit JVM≧32GB) val ue _mark _klass _mark _mark val ue _klass val ue _klass val ue long Long(32bit JVM) Long(64bit JVM<32GB) Long(64bit JVM≧32GB) value _mark _klass _mark _mark value _klass _klass value value 詳細は チラシで
9.
JUSTSYSTEMS 基本型とラッパークラス • -Xmx32g(厳密には-Xmx32767m~)を境にメモリ使 用量が増える理由 圧縮Oops(CompressedOops)が無効になり、オブジェクト参 照(klassヘッダー)が4→8バイトになるため •
4バイト(32bit)で識別可能なアドレス空間は4GB(== 2^32) • Javaオブジェクトのアドレスは8バイトでアラインメントされているため、 下位3bitは常に0 • (bbbbbbbb bbbbbbbb bbbbbbbb bbbbb000のビットパターン) • 3bitシフトで35bitのアドレス空間を32bitで識別できる(35bit→32GB) • (-Xmx32g以下でも-XX:-UseCompressedOopsで無効にできる) 9
10.
JUSTSYSTEMS Javaオブジェクトの構造(再) • たいていの場合、単一ではなくオブジェクト内にオブジェク トへの参照を持っている • 例えば形態素解析辞書の場合 •
一つの単語は表記・品詞・解析用情報からなる class 単語 { String[] 表記; // 表記ゆれ対応のため複数 int 品詞; int 解析用パラメータ; } • 辞書は単語の集合 class 辞書 { 単語[] words = new 単語[100万とか]; } 10
11.
JUSTSYSTEMS Javaオブジェクトの構造(再) "バイオリン", "ヴァイオリン"表記を持つ単語の場合 • 132バイト中58バイト(44%)が管理情報またはパディング •
構造はJVMの実装により異なる(上記は32bit JVM) • 32bitポインタ/8バイトアラインメント オブジェクトの数が増えると、想定以上にメモリ消費量が増大 11 class 単語 class String[] String char[] 単語: _mark _klass _mark _klass _mark _klass _mark _klass 表記: 品詞:xxxx length:2 value: hash:xx length:5 'バ' 'イ' 解析:yyyy value: value: 'オ' 'リ' 'ン' String char[] _mark _klass _mark _klass value: hash:yy length:6 'ヴ' 'ァ' 'イ' 'オ' 'リ' 'ン'
12.
JUSTSYSTEMS いろいろなオブジェクトのメモリ使用量 クラス/オブジェクト 32bit JVM 64bit
JVM 32GB未満 64bit JVM 32GB以上 new String("https://[^/]+/") ※Java8 56 72 88 new String("https://[^/]+/") ※Java9 56 72 "https://[^/]+/".toCharArray() 40 48 56 "https://[^/]+/".getBytes("UTF-8") 32 32 40 Pattern.compile("https://[^/]+/") 1080 1128 1256 new Date() 24 24 32 new Timestamp() 24 32 40 Calendar.getInstance() ※GregorianCalendar 424 448 544 ZonedDateTime.now() 88 120 152 LocalDateTime.now() 48 72 80 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S") 1232 1296 1880 DateTimeFormatter.of("yyyy-MM-dd HH:mm:ss.S") 432 456 704 • StringはJava9でサイズが小さくなった(Latin-1の文字は1byteで保持するため) • Patternなどはstaticに持っておくとよい。 • GregorianCalendarが意外と大きい。 • SimpleDateFormatはスレッドセーフでないので、同期化するかDateTimeFormatterに乗り換える。 • etc... 12 詳細は チラシで
13.
JUSTSYSTEMS メモリ使用量の削減 13
14.
JUSTSYSTEMS 基本型を使う • 単語を全て基本型の配列に押し込む class 辞書(メモリ節約版)
{ char[] 全単語の表記; // 表記揺れ数→表記長→表記の順に格納 int[] 全単語の表記への開始位置の配列; int[] 品詞の配列; int[] 解析用パラメータの配列; } • 前述の辞書のメモリ使用量は・・・3分の1以下に! • ただし、ソース可読性・メンテナンス性が犠牲に・・・ クラス メモリ使用量 [MB] 32bitVM 64bitVM 32GB未満 64bitVM 32GB以上 辞書 109.3 132.0 180.0 辞書(メモリ節約版) 32.0 32.0 32.0 14
15.
JUSTSYSTEMS 基本型の配列をさらに詰める • Boolean[ ]
→ 4または8バイト x 要素数 • Boolean.TRUE/FALSEを格納した場合。new Boolean(true/false)はやめましょう 。 • boolean[ ] → 1バイト x 要素数 • BitSet → 1ビット x 要素数 (内部はlong[ ]配列) • 要素数100万の場合、BitSetはBoolean[ ]の16分の1以下、 125KBに! 32bitVM 64bitVM 32GB未満 64bitVM 32GB以上 new Boolean[100万] 4MB 4MB 8MB new boolean[100万] 1MB 1MB 1MB new BitSet(100万) 125kB 125kB 125kB • BitSetをさらに圧縮する方法もあるが、難しいのでここでは割愛 15 詳細は チラシで
16.
JUSTSYSTEMS 基本型の配列をさらに詰める • booleanをBitSetに詰めたのと同様、整数配列の最小値~最大値が N bit(N≪整数型のビット幅)で表現できるとあらかじめ分かっている場合、配列 に隙間なく詰め込むことで圧縮できる(ただし取得にbit演算が必要になる) •
データ依存で効果が異なる • どんなデータもコンスタントに圧縮できる方法はなかなかない • 伸張速度も重要、用途によってはランダムアクセスも必要 long: val1 long: val2 long: val3 long: val4 val1 val2 val3 val4 ... ... long値の配列の最小値~最大値が64bitよりも小さなbitで表現できる場合 値のバリエーションが少ない場合も、値→IDの変換表を作ることでも圧縮 ID 値 1 123456 2 98765432 3 123456789 123456789 123456 98765432 123456 3 1 2 1 ... ... 16
17.
JUSTSYSTEMS ライブラリの利用 17
18.
JUSTSYSTEMS Collection @since 1.2 •
Java Collection Framework • List, Map, Set等の頻出するデータ集合に対する 統一されたインターフェイスを提供 • 検索やソート等の高性能実装 • 一般には、使いやすく、高品質、高性能 • ただし、メモリ使用量に関しては・・・ 18
19.
JUSTSYSTEMS Autoboxing @since 1.5 •
一見基本型を使っているようだがラッパークラスに Set<Integer> set = new HashSet<Integer>(); set.add(1234); // 実際にはnew Integer(1234) が追加 • 基本型を指定しても、自動的にIntegerが生成され格納さ れる(4バイトではなく16バイト以上消費) • さらに、HashSet/HashMapは内部でMap.Entryを生成して key/valueを格納するため、その分のメモリも消費・・・ 19
20.
JUSTSYSTEMS 省メモリコレクションライブラリ • fastutil, Eclipse(GS)
Collections, HPPC, koloboke, troveなど • Map/Set<? extends Number>の値を基本型で持つことで省メモリ化 • JDKのHashMap<K,V>/HashSet<K>に比べ1/5以下のメモリ使用量 ■100万個のint値を保持した集合のメモリ使用量と検索時間(実測値) コレクションクラス メモリ使用量 [MB] 検索時間 [ns/エントリ] 32bitVM 64bitVM 32GB未満 64bitVM 32GB以上 32bitVM 64bitVM 32GB未満 64bitVM 32GB以上 int[ ] (検索はバイナリサーチ) 4.0 4.0 4.0 165 154 159 java.util.HashSet<Integer> 48.4 56.4 88.8 166 68 74 it.unimi.dsi.fastutil.ints.IntOpenHashSet *1 8.4 8.4 8.4 30 39 25 org.eclipse.collections.impl.set.mutable. primitive.IntHashSet *2 8.4 8.4 8.4 53 50 33 com.koloboke.collect.impl.hash. MutableLHashIntSet *3 8.4 8.4 8.4 31 23 23 com.carrotsearch.hppc.IntHashSet *4 8.4 8.4 8.4 35 28 21 *1 fastutil → http://fastutil.di.unimi.it/ *2 Eclipse Collections → https://www.eclipse.org/collections/ja/ *2 koloboke → https://koloboke.com/ *4 hppc → https://labs.carrotsearch.com/hppc.html 20
21.
JUSTSYSTEMS 省メモリコレクションライブラリ • オブジェクトを入れる場合も、key/valueの格納にMap.Entry<K,V>を使わず Object[] に詰め込んでいるため、JDKのHashMap/HashSetより省メモリ //
char[]とbyte[]を両方扱えるHash.Strategy(fastutil用) // ObjectOpenCustomHashSetに設定して利用 // ※Latin-1の文字列の場合byte[ ]、 // それ以外はchar[ ] をput()/add()する class PrimitiveArrayHashStrategy implements Hash.Strategy<Object> { public int hashCode(Object o) { if (o == null) { return 0; } if (o instanceof byte[]) { return Arrays.hashCode((byte[]) o); } else if (o instanceof char[]) { return Arrays.hashCode((char[]) o); } else { /* エラー */ } } public boolean equals(Object a, Object b) { if (a == b) { return true; } if (a instanceof byte[]) { return b instanceof byte[] && Arrays.equals((byte[]) a, (byte[]) b); } else if (a instanceof char[]) { return b instanceof char[] && Arrays.equals((char[]) a, (char[]) b); } return false; } } コレクションクラス メモリ使用量 [MB] 32bitVM 64bitVM 32GB未満 64bitVM 32GB以上 Java8 Java8 Java9 Java8 Java9 HashSet<String> 111.6 128.4 104.4 168.8 144.8 ObjectOpenHashSet <String>(fastutil) 87.6 96.4 72.4 120.8 96.8 ObjectOpenCustom HashSet<Object> *1 48.4 48.4 48.4 64.8 64.8 ■Latin-1の文字列100万個を保持したSetのメモリ使用量 • さらに、fastutilのHash.StrategyやEclipse(GS) CollectionsのHashingStrategy, kolobokeのEquivalence を使うと、hashCode()やequals()を持たないクラスのオブ ジェクトをMapやSetに格納できる • プリミティブ配列も使えるので、Stringの代わりにchar[ ] やbyte[ ]を入れられるMap/Setが作れる *1 全てbyte[ ]で格納されているため、省メモリ 21
22.
JUSTSYSTEMS 省メモリコレクションライブラリ • (先ほどの辞書クラスと同様)文字列ごとのbyte[ ]
を1つのbyte[ ]に詰め込む HashMap/HashSetを考えると、さらにメモリが節約できる(→32.5MB) • さらに圧縮するなら、アルゴリズム/データ構造から変える必要がある // byte[]に全文字列を詰め込むHashSet/Map class ByteArrayStringHashSet { // Latin-1かどうかと文字列長と文字列本体を // 詰め込んだbyte配列 private byte[] buffer; // エントリごとのbufferへのオフセット // ハッシュ値ごとにまとめて格納 private int[] offsets; // 詳細は →https://en.wikipedia.org/wiki/Hash_table#O pen_addressing // Mapとして使う場合に値を格納する配列 // private Object[] values; } コレクションクラス メモリ使用量 [MB] 32bitVM 64bitVM 32GB未満 64bitVM 32GB以上 Java8 Java8 Java9 Java8 Java9 HashSet<String> 111.6 128.4 104.4 168.8 144.8 ObjectOpenHashSet <String>(fastutil) 87.6 96.4 72.4 120.8 96.8 ObjectOpenCustom HashSet<Object> (前ページ) 48.4 48.4 48.4 64.8 64.8 ByteArrayStringHash Set (右図) 32.5 32.5 32.5 32.5 32.5 org.trie4j.louds. TailLOUDSTrie *1 24.6 24.7 24.5 24.7 24.5 ■Latin-1の文字列100万個を保持したSetのメモリ使用量 • 例えばLOUDS Trieなど(→ 24.6MB) *1 trie4j → https://github.com/takawitter/trie4j 22
23.
JUSTSYSTEMS まとめ • Javaのオブジェクトは1つ1つ参照としてしか生成できず、大量の インスタンスを生成するとメモリ消費のオーバーヘッドが無視でき なくなる • メモリ使用量が高止まりするとガベージコレクションの負荷も上がってしまう。 •
用途によってはプリミティブ型や高効率のOSSライブラリを活用す ることでメモリ使用量を節約できる • プリミティブ型を使うとソースの可読性やメンテナンス性が犠牲になる場合も。 • 実装時間が余計にかかったり、バグが残存しやすいのも悩みどころ。 • いくらがんばってもメモリに乗らないものは乗らない • コレクションを使うときに、何をどれくらいの入れるかやスコープ・ライフサイクルを 常に意識することが大切。 • そのためにもメモリ使用量を見積もったり計測するノウハウを持っておく。 • 乗らないものはあきらめて一時ファイルやDBを使う。 結局は適材適所 23
24.
JUSTSYSTEMS 付録 24
25.
JUSTSYSTEMS メモリ使用量の計測方法 ① Runtime.totalMemory() –
Runtime.freeMemory() • 一番お手軽。GC前のメモリも計測されるので、System.gc()してから計測する。(が、頻繁に計 測すると性能に影響が) ② MemoryMXBean (ManagementFactory.getMemoryMXBean()) • init, used, committed, max がそれぞれ取得可能。 ③ MemoryPoolMXBean (ManagementFactory.getMemoryPoolMXBeans()) • Eden, Survivor, Tenuredそれぞれ取得可能 (G1GCだと名前が変わる。 G1 Old Genとか) ④ com.sun.management.ThreadMXBean (Oracle JDK限定) • getThreadAllocatedBytes()でオブジェクト生成前後のヒープ量が差分が取れる。 • オブジェクト生成で一時的に確保されたヒープも計測されてしまうようなので注意が必要。 ⑤ Instrumentation.getObjectSize() • オブジェクトの正確なメモリ使用量が計測可能。 • premain()を実装したjarを-javaagent:...でJVM引数に指定する。 • 参照先のオブジェクトは計測できない →Reflectionを駆使して参照を辿りながら計測する必要あり。 ⑥ sun.misc.Unsafe.objectFieldOffset(Field f) • Fieldのオフセットが取得できる→全フィールドのオフセットの最大値+サイズでオブジェクトの サイズが計測できる。(アラインメントの考慮は必要) • 参照先をReflectionで辿って合計する必要があるのはInstrumentationと同じ。 25
26.
JUSTSYSTEMS 今後に向けて • JEP 169:
Value Objects http://openjdk.java.net/jeps/169 • クラスインスタンスの配列がメモリ上で連続して取れる • new 単語[100万]でもメモリ効率が落ちない。 • ネストするオブジェクト(単語.表記など)の扱いは別途工夫する必要があるかも。 • mark/klassのオーバーヘッドがなく、メモリ上でも近接しているため速度向上も期待できる • JEP 218: Generics over Primitive Types http://openjdk.java.net/jeps/218 • Map<int, int>とか。実装はサードパーティ任せ? • Array 2.0(Project Panama) http://openjdk.java.net/projects/panama/ • 2次元配列(従来だと1次元配列のオブジェクト配列)をメモリ上で連続して確保。 • メモリ効率を上げるためにnew int[m x n] のように1次元に詰め込んでいたのが、普通の2次 元配列(int[m][n])のようにでき、可読性と性能向上が期待できる。 • これらの導入で、自然言語処理や大規模データ処理でますますJavaが使え るようになるはず・・・ 26
27.
JUSTSYSTEMS その他の小技 • 省メモリな固定数コレクション • 空の場合、Collections.emptyList()/emptySet()/emptyMap() •
シングルトンの場合、 Collections.singletonList()/singleton()/singletonMap() • 2個以上の場合、Eclipse Collectionsの org.eclipse.collections.impl.list.fixed.DoubletonListなど • 同じオブジェクトをN個返す場合、Collections.nCopies(Object o) • Enumの場合、HashMap/SetよりEnumMap/Setが省メモリ • 数値型オブジェクトのキャッシュ • -128(Characterの場合は0)~127の場合、 Byte/Short/Character/Integer/Longはstaticにキャッシュされたインスタ ンスを返す • Integerのみ、-XX:AutoBoxCacheMax=<size>で上限を増やせる。 • BigDecimalの0~10も同様。BigIntegerは-1,0,1,2,10だけ。 27
28.
JUSTSYSTEMS ご清聴ありがとうございました 今回はメモリ節約についてご紹介しました 株式会社ジャストシステムでは多種多様な商品を 開発しており、さまざまな技術を活用しています 興味のある方、お声がけください • 「できる」になれるコンテンツ:Java100本ノック • https://github.com/JustSystems/java-100practices •
ジャストシステムのエンジニア特集ページ • https://www.justsystems.com/jp/employ/engineer/ 28