9

この質問によると、Javaでオブジェクトのメモリサイズを決定する標準的な方法は、java.lang.instrumentationを使用することです。いくつかの調査の結果、これを実現するためのScala固有の方法はないように思われるため、ここでもJavaアプローチを適用する必要があります。

残念ながら、Javaのバックグラウンドを持たないScalaプログラマーにとって、この手法をScalaに適応させることは完全に簡単ではありません。私の質問は次のとおりです。

質問1

ここで何が起こっているのですか?別のJARにクラスを配置する必要がある理由は、ObjectSizeFetcherそれを使用する実際のプログラムの前に、何らかの方法でクラスがロードされるようにするためだと思います。Premain-Classエントリとパラメータがないとインストルメンテーションを使用できないと思います-javaagent:TheJarContainingObjectFetcher.jarか?

質問2

SBTで完全なワークフローを実装する簡単な方法はありますか?現在、やや面倒な解決策しかありません。最初に、セカンダリSBTプロジェクトをセットアップして、それを定義ObjectSizeFetcherしてJARにパッケージ化する必要があります。Premain-Classこれまでのところ、パッケージ化中にエントリをJARに自動的に追加する方法がわからなかったため、手動で解決する必要がありました。結果のJARを、使用したいプロジェクトのローカルライブラリに追加できますgetObjectSize。このプロジェクトでは、を有効にfork in runして使用する必要がありますjavaOptions in run += "-javaagent:TheJarContainingObjectFetcher.jar"。既存のSBTプロジェクト内でインストルメンテーションをすばやく使用するためのより単純な(そして邪魔にならない)ワークフローはありますか?Premain-Classたぶん、このセカンダリJARを不要にすることについてSBTに直接伝えることができますか?

質問3

Scalaでオブジェクトのメモリ使用量を評価するためのまったく異なる方法をお勧めしますか?

4

2 に答える 2

2

回答 3: JOL (Java Object Layout)ktoso/sbt-jolを表示するもの、つまり JVM のオブジェクト レイアウト スキームの分析を見ることができます。

// project/plugins.sbt
 addSbtPlugin("pl.project13.sbt" % "sbt-jol" % pluginVersionHere)

It does include the size:

> jol:internals example.Entry

...
[info] example.Entry object internals:
[info]  OFFSET  SIZE   TYPE DESCRIPTION                    VALUE
[info]       0    12        (object header)                N/A
[info]      12     4    int Entry.value                    N/A
[info]      16     4 String Entry.key                      N/A
[info]      20     4        (loss due to the next object alignment)
[info] Instance size: 24 bytes
[info] Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
于 2016-06-16T08:36:17.140 に答える
2

回答 1: はい。インストルメンテーションが必要な場合は、インスタンスを取得する必要があります。おそらく、Premain-Class と -javaagent がないと取得できないでしょう。

回答 2: クラスローダーを使用して、(Java または Proguard を使用した Scala で) 非常に単純なブートストラップ プロジェクトを作成できます (必要になる場合もあります)。2 つの理由があります。

第一の理由:利便性。java.net.URLClassLoader を使用して、標準の Scala ライブラリとプロジェクトのクラス ディレクトリを含めることができます。テスト時に JAR に再パッケージ化する必要はありません。

2 番目の理由: JAR 地獄の防止。Scala がバイナリ互換でないことはおそらくご存知でしょう。また、Java エージェントがアプリケーションと同じクラスローダーにロードされることも知っておく必要があります。クラスローダに Scala ライブラリが含まれている場合、アプリケーションは単に別の Scala バージョンを使用することはできません。

ただし、Java エージェントが Scala ライブラリを直接使用しない場合 (たとえば、ブートストラップ アプリケーションであり、実際のエージェントとそのライブラリを別のクラスローダーにロードする場合)、計測されたアプリケーションは任意の Scala ライブラリを自由に使用できます。

回答 3: インストルメンテーションも使用するでしょう。

于 2013-01-04T19:04:33.590 に答える