Skip to content

Instantly share code, notes, and snippets.

@lyricallogical
Last active December 15, 2015 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lyricallogical/5306010 to your computer and use it in GitHub Desktop.
Save lyricallogical/5306010 to your computer and use it in GitHub Desktop.
java で巨大なバッファを取得しようとした際にブロック(Thread.sleep)するために生じる性能上の問題に関する考察 がちゃぴんさん(@kosaki55tea) が RT された以下のツイートに触発されて調査、考察しました https://twitter.com/frsyuki/status/319546145082863616 https://twitter.com/frsyuki/status/319546516316499969 https://twitter.com/frsyuki/status/319547103296774145 適当に突っ込んでみたエスパーツイート https://twitter.com/lyrical_logical/status/3195553…

以下の考察は openjdk のコードを元にしているため、oracle だとまた違うかもしれない。

map0 でめでたく native からヒープをがさっと取ってこれた場合、色々あった末に DirectBuffer を implements した DirectByteBuffer とやらが具象クラスとなる。 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/nio/DirectByteBuffer.java DirectBuffer は自身の確保したリソースを開放する役割を持つオブジェクト Cleaner を返すメソッドを持っており、clean の処理は Unmapper に委譲される。 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/FileChannelImpl.java#FileChannelImpl.Unmapper Cleaner は「オブジェクトが phantom reachable になった際に後処理を行いたい場合に利用するクラス」であり、ぶっちゃけ普通は出番ない。 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/misc/Cleaner.java

ここから推測。

恐らく Cleaner を利用したのは lifetime の観点からみて、native ヒープから取ってきたバッファも vm ヒープから取ってきたバッファも、同じになるようにしたかったのではないかと考えられる。 finalize で munmap すると lifetime の観点からみて同じにはならない。オブジェクトは GC によって回収済みだけれど、ファイナライズ待ち、という状態が生まれるため。 これのモチベーションというかメリットは finalize で munmap する場合、ファイナライザキューにオブジェクトが積まれた後、ファイナライザが finalize を処理するまで munmap が遅れてしまうのを避けることができる、というところだと思う。前提条件として、対照のオブジェクトが finalize メソッドを実装していない(ため、ファイナライザキューには積まれない)、が必要。 今のところ他に解釈を思いつかない…

というわけで、可及的速やかに munmap が行われるように実装されてはいるのだけれども、とはいえ GC がオブジェクトを回収するタイミングの予測などは不可能なので、今回ようなありがちなアドホックなコードが結局書かれてしまうのだった…という話だと思う。 https://gist.github.com/frsyuki/6fce6a75a0c400740dd3 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/FileChannelImpl.java#790

結論としては、特に対処方法はなし(ワー)

追記:対処法()https://twitter.com/lyrical_logical/status/319579499794661376

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment