Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Too many open files' with mmap=True #104

Closed
takanory opened this issue Sep 29, 2021 · 7 comments · Fixed by #107
Closed

'Too many open files' with mmap=True #104

takanory opened this issue Sep 29, 2021 · 7 comments · Fixed by #107
Milestone

Comments

@takanory
Copy link

  • macOS 11.6
  • Python: 3.9.7
  • Janome: 0.4.1

同一のコードでTokenizerの初期化がmmap=TrueだとToo many open filesが発生します

from janome.tokenizer import Tokenizer

for i in range(10):
    t = Tokenizer(mmap=True)  # or False
    print(i)
    for _ in t.tokenize('すもももももももものうち'):
        pass
$ ulimit -n
256
$ python sample.py  # mmap=False
0 1 2 3 4 5 6 7 8 9 
$ python sample.py  # mmap=True
0 1 2 3 4 5 Traceback (most recent call last):
  File "/Users/takanori/Project/manaviria/djangoapp/apps/work/sample.py", line 4, in <module>
  File "/Users/takanori/Project/manaviria/djangoapp/apps/work/env/lib/python3.9/site-packages/janome/tokenizer.py", line 177, in __init__
  File "/Users/takanori/Project/manaviria/djangoapp/apps/work/env/lib/python3.9/site-packages/janome/sysdic/__init__.py", line 83, in mmap_entries
OSError: [Errno 24] Too many open files
@nakagami
Copy link
Contributor

Tokenizer のインスタンスをループの外側で生成するのが良いと思います

from janome.tokenizer import Tokenizer

t = Tokenizer(mmap=True)  # or False
for i in range(10):
    print(i)
    for _ in t.tokenize('すもももももももものうち'):
        pass

@mocobeta
Copy link
Owner

mocobeta commented Sep 29, 2021

レポートありがとうございます。
複数Tokenizerオブジェクト間でfile descriptorを使い回せれば解消すると思いますが,OSごとにmmap実装の分岐が必要な気がします。
とりいそぎの回避策としては, @nakagami さんのコメントで回避できますね。

@takanory
Copy link
Author

回答ありがとうございます。
あ、これは問題を報告するために単純化したコード例で示しているだけで、nakagamiさんの書いた回避策については認識しています。

実際のコードでは django の API の中で t = Tokenizer(mmap=True) が呼び出されており、このAPI呼び出しが何回か行われると Too many open files が発生するというものでした。

実際のコード上では mmap=False にして問題を回避しています。

試していませんが以下でも回避はできるのでは、と思っています。

  • モジュールグローバルで t = Tokenizer() する
  • functools.cache() でキャッシュする

Janome全体としても、file descriptorの使い回しは大変そうなので、キャッシュすると回避できるかも知れないなと思いました。

以上です。

@mocobeta
Copy link
Owner

mocobeta commented Sep 29, 2021

Linux のデフォルトulimit (open files) がかなり制限されているので,簡単に発生しますね...。

@mocobeta
Copy link
Owner

@ghost
Copy link

ghost commented Aug 8, 2022

あのーこのバグは私が #100 で報告してたと思うんですが、そっちでは「ドキュメント読め、うちらはサポートデスクじゃない」と言われてしまいました。
ビックリして自分のコメントをいくつか消してしまったんですが。
私のレポートに不備があったなら改善したいんですがもしよかったらどこに不備があったか教えてくださいませんか?
返事は期待しないで待ってます。

@mocobeta
Copy link
Owner

mocobeta commented Aug 8, 2022

@Narupo すみません, #100 は私の勘違いですね.レポートに不備はなかったと思います.

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

Successfully merging a pull request may close this issue.

3 participants