2012-11-20 10 views
7

私のプロジェクトは最大1Mの原子を吹き飛ばしましたが、私たちは限界を突き詰めましたが、人々がlist_to_atomとその友人に関して提出するコードにいくつかの正気を適用する必要があります。登録されているすべての原子のリストを取得することから始めて、最大の犯罪者がどこにいるか確認できます。これを行う方法はありますか?私はそれをどのようにするかについて創造的でなければならないので、ライブコンソールに1~2Mの回線をダンプしようとはしません。Erlang:現在登録されているすべての原子のリストを取得できますか?

ありがとうございました。

答えて

5

ライブシステムで実行する方法があるかどうかはわかりませんが、テスト環境で実行できるのであれば、クラッシュダンプ経由でリストを取得できるはずです。原子テーブルはcrash dump formatの末尾にあります。 erlang:halt/1経由でクラッシュダンプを作成できますが、これはランタイムシステム全体を停止させます。

+1

まあ、私はおそらく周りにクラッシュダンプを持っているので、それは悪い方法ではないです。たぶん、私はerlangのソースを掘り下げ、それがどのようにそれを得るのかを見ていきます。ちょっと創造的なハッカーで、多分私はライブコンソールから入ることができます。 – Sniggerfardimungus

+1

Recon https://github.com/ferd/reconは、クラッシュダンプの解析をサポートしています。 – rvirding

0

EDITED(間違った答え...)

あなたはそれが必要なとき、私は非常に少数のユースケースを知っている..but +t

http://www.erlang.org/doc/efficiency_guide/advanced.html

での原子の数を調整することができます。

あなたは私はあなたが1M原子よりも多くを使用する場合は、あなたが何か間違ったことをやっていると言うあえてerlang:memory()

+1

登録されたプロセス/ポートだけの 'erlang:registered/0'はありませんか?私はそれが原子テーブル全体をダンプするとは思わない。すなわち、 'list_to_atom'を呼び出すことがこのリストに追加されるとは思わない。 – Tadmas

+0

あなたは正しいです..私は質問を理解していません – user425720

+0

はいくつかのヒントを、おそらく助けてくれました – user425720

3

と原子の統計情報を追跡することができます。原子は、アプリケーションが実行されるとすぐに静的になるように意図されているか、または中程度のサイズのアプリケーションでは少なくとも3000、またはそれ以上の数の上限で境界を定められています。

敵があなたのVMにアトムを生成できるときは、十分に注意してください。特にlist_to_atom/1のような呼び出しはやや危険です。

+0

はい、あなたは本当に間違って何かをしているerlangに10^6以上の原子を持っている場合 –

26

外部用語形式の文書化されていない機能を使用して、すべての原子を保持することができます。

外部用語形式でエンコードされたErlangの用語は、バイト131、次にタイプを識別するバイト、そして実際のデータで始まります。 EEP-43にはATOM_INTERNAL_REF3(バイトタイプ75)という可能なタイプがすべて記載されていますが、これはofficial documentation of the external term formatには記載されていません。

ATOM_INTERNAL_REF3の場合、データはアトムテーブルへのインデックスであり、24ビット整数としてエンコードされます。私たちは、簡単なバイナリを作成することができます。たとえば<<131,75,N:24>>

を、私のErlangのVMで、falseはアトムテーブルのゼロ番目の原子のようだ:

> binary_to_term(<<131,75,0:24>>). 
false 

原子の数を見つけるための簡単な方法はありません現在原子表*にありますが、badargエラーが発生するまで番号を増やすことができます。

だから、この小さなモジュールは、あなたのすべての原子のリストを与える:出力がどのように見える

-module(all_atoms). 

-export([all_atoms/0]). 

atom_by_number(N) -> 
    binary_to_term(<<131,75,N:24>>). 

all_atoms() -> 
    atoms_starting_at(0). 

atoms_starting_at(N) -> 
    try atom_by_number(N) of 
     Atom -> 
      [Atom] ++ atoms_starting_at(N + 1) 
    catch 
     error:badarg -> 
      [] 
    end. 

のErlang/OTP 20.0で
> all_atoms:all_atoms(). 
[false,true,'_',[email protected],'$end_of_table','','fun', 
infinity,timeout,normal,call,return,throw,error,exit, 
undefined,nocatch,undefined_function,undefined_lambda, 
'DOWN','UP','EXIT',aborted,abs_path,absoluteURI,ac,accessor, 
active,all|...] 
> length(v(-1)). 
9821 

*、あなたが呼び出すことができますerlang:system_info(atom_count)

+1

今は素敵なトリックです! (http://www.relatably.com/m/img/clever-girl-meme-gif/fa3e19ffd513583d5f7ae60382262d9a0505d72589cd2374af2b2a7de75e057d.jpg) – RichardC

関連する問題