根据this question,在Java中确定对象内存大小的标准方法是使用java.lang.instrumentation。经过一些研究,看起来没有Scala特定的方法来实现这一点,因此Java方法也应该适用于此。
不幸的是,对于没有Java背景的Scala程序员来说,在Scala中调整这种技术并不是完全简单的。我的问题是:
问题1
这到底发生了什么?我想我们必须将类ObjectSizeFetcher
这样的类放在一个单独的JAR中的原因是为了确保它在我们想要使用它的实际程序之前以某种方式加载。我假设在没有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项目中的仪器?也许我可以直接告诉SBT Premain-Class
是否需要使用这个辅助JAR?
问题3
您是否会建议使用完全不同的方法来评估Scala中对象的内存使用情况?
答案 0 :(得分:2)
答案1:是的,如果你想要iinstrumentation,你需要得到一个实例。没有Premain-Class和-javaagent,你可能无法得到它。
答案2:您可以(并且可能需要)使用类加载器并创建一个非常简单的引导项目(在Java中或在Scala中使用Proguard)。有两个原因:
第一个原因:方便。您可以使用java.net.URLClassLoader包含标准Scala库和项目的classes目录。测试时,您不再需要在JAR中重新打包它。
第二个原因:防止JAR地狱。您可能知道Scala不是二进制兼容的。您还应该知道Java代理程序在同一个类加载器中加载了应用程序。如果类加载器包含Scala库,则应用程序不能简单地使用另一个Scala版本。
但是,如果Java代理不直接使用Scala库(例如,它是一个引导应用程序并将真实代理及其库加载到另一个类加载器中),则已检测的应用程序可以自由使用任何Scala库。
答案3:我也可能会使用仪器。
答案 1 :(得分:2)
答案3:您可以查看显示ktoso/sbt-jol
的JOL (Java Object Layout),即JVM中对象布局方案的分析
# Set up the detector with default parameters.
detector = cv2.SimpleBlobDetector()
# Detect blobs.
keypoints = detector.detect(image)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(image, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show keypoints
final = Image.fromarray(im_with_keypoints)
final.show()