0

说我有课

class A{
  //code for class A
}


class B{
  //code for class B
}

class A{
  public static void main(String a[]){
    //Initialize m instances of A and n instances of B and store each in arrays
    //Equate any arbit index in the array to null
  }
}

在这种情况下,我的主要目标是随时在内存中找到 A 类和 B 类的所有活动实例。

我想必须可以使用调试器。

但是,由于某种原因(原因超出了问题的范围),我需要从代码本身中获取实例。因此,我需要一个像

public void getAllActiveInstances(){
  //Print values
}

编辑:我不需要实例来操作它们。我只需要知道它们是否存在。这主要用于调试目的。如果这是不可能的,那么请解释如何使用调试器来做同样的事情。

4

3 回答 3

2

简短的回答是否定的,您不应该在任何时候使用 java 查看内存。

长答案是,如果在 GC 收集对象后有任何方法可以访问对象,那么您就违反了 GC 的原则,即只收集执行代码无法以任何方式到达的东西。垃圾收集的内存被释放并返回给程序来做它想做的任何事情。这意味着如果您已经对对象 A 进行了 GC,则允许 java 将任意数量的东西写入该位置,从而破坏该内存块的“A-ness”。尝试读取现在存储在该内存块中的对象 B 并假装它是 A 会导致各种问题。

展望未来:要跟踪您创建的所有类,我建议修改类本身。您的类可以有一个static容器(如 a HashMap),并且构造函数将构造的类添加到HashMap. 但是,请注意,由于您正在使用对所有已创建对象的引用,垃圾收集将永远不会收集这些对象并释放该内存。

于 2012-06-11T13:53:58.813 回答
1

“在这种情况下,我的主要目标是随时在内存中找到 A 类和 B 类的所有活动实例,而不管垃圾收集器是否删除了对象。”

如果垃圾收集器已将其删除,则它不会是活动实例,也不会是任何类型的实例。

没有用于此的 Java API,当然 JRockit Flight Control 和/或调试器可以为您执行此操作,但如果您想要一种实际的编程方式,您将不得不手动滚动它。祝你好运,让它可靠。您可能需要使用构造函数和终结器来增加和减少对象数量。

不要尝试实现自己的对象池,除非你真的,真的认为你可以在自己的游戏中击败热点优化器。

于 2012-06-11T13:56:55.437 回答
1

正如您提到的,您可以使用调试器来完成。Java 提供调试 API。您可以实现自己的调试器并连接到应用程序本身。

另一种方法是检测你的课程。我知道以下技术:

  1. 使用存储对必须监视的所有实例的引用的特殊工厂来实例化它们。
  2. 使用 AOP(例如 AspectJ)。方面会将创建的实例注册到存储库中(如上所述)
  3. 使用java 检测包动态更改类。看看SizeOf - 一个使用 java 检测 API 的非常简单的项目。你可以用它作为例子来学习这个问题。
于 2012-06-11T14:01:20.937 回答