在Java中,是否有方法跟踪在堆或堆栈中创建的变量、方法或类?

在Java中,是否有方法跟踪在堆或堆栈中创建的变量、方法或类?,java,memory,heap-memory,stack-memory,Java,Memory,Heap Memory,Stack Memory,我试图完全理解Java如何使用其内存安排。互联网上的讨论非常混乱,有时相互矛盾,所以我找不到可以信任的人。如果它与静态、静态方法、局部变量、线程、volatile等混合在一起,那么它可能会非常复杂。所以我在想,如果有一种方法可以让我自己在做一些Java编码实验时研究它。类MemoryTrack执行类似的操作 public myMethod(){ int i = 0; MemoryTrack.show(new myClass()); //print out "Heap at address 111

我试图完全理解Java如何使用其内存安排。互联网上的讨论非常混乱,有时相互矛盾,所以我找不到可以信任的人。如果它与静态、静态方法、局部变量、线程、volatile等混合在一起,那么它可能会非常复杂。所以我在想,如果有一种方法可以让我自己在做一些Java编码实验时研究它。类MemoryTrack执行类似的操作

public myMethod(){
int i = 0;
MemoryTrack.show(new myClass()); //print out "Heap at address 111"
MemoryTrack.show(new myClass()); //print out "Heap at address 222"
MemoryTrack.show(i); //print out "Stack at address 333"
MemoryTrack.show("a static method");  //print out "stack at address 444"
}

内存的使用如中所述。堆栈存储堆栈帧(包含局部变量和部分结果)。堆是所有类实例和数组的来源。堆栈帧也可以从堆中分配(然后推送到堆栈上)。还有方法区域和运行时常量池内存。规范中详细说明了细节


至于监视内存使用情况,一些探查器都有相应的工具。要从程序内部进行监控,请查看类(以及
java.lang.management
包中的相关类)。它很容易使用。虽然它可能不会给你听起来像你想要的一切,但它可能是最好的选择。

规则非常简单:堆包含对象,堆栈包含局部变量和方法参数。对象字段位于堆中的对象内部。不知道静态字段。方法和构造函数既不存储在堆栈中,也不存储在堆中。线程和volatile并不重要


方法调用在堆栈上。每个都有一个为其保留的空间,即堆栈框架,其中包含本地变量和参数。

您可能认为Java中的所有变量都在堆上。实际上,它取决于实现。

您需要知道两件事

  • 它没有你想象的那么复杂
  • 99%的情况下这并不重要

变量总是在堆栈上

对象总是在堆上。(有例外,但我不担心)

方法和类总是在perm gen中

在HotSpot/OpenJDK JVM中,静态字段收集在类的单例对象中。如果执行堆转储,则可以看到该实例。其他JVM的做法可能有所不同

类MemoryTrack执行类似的操作

public myMethod(){
int i = 0;
MemoryTrack.show(new myClass()); //print out "Heap at address 111"
MemoryTrack.show(new myClass()); //print out "Heap at address 222"
MemoryTrack.show(i); //print out "Stack at address 333"
MemoryTrack.show("a static method");  //print out "stack at address 444"
}

这样的方法不会做任何有用的事情,因为参数总是在堆栈上,它引用的对象总是在堆上。您无法以标准方式获取对象的内存位置,如果它这样做了,它就不太可能有用,因为它随时都可能发生变化。

为什么不将此作为答案发布呢?无论如何,Java的一部分要点是,您不应该关心堆上的内容和堆栈上的内容--事实上,JIT有时可以判断出堆栈上的某些东西通常会在堆上。@LouisWasserman它在某些大范围应用程序中可能很重要,但在大多数情况下并不重要。实际上,它在。唯一依赖于实现的特性是堆栈的结构,堆栈帧是否从堆中分配,以及与OP的问题相关的一些其他问题。这个主题的语言几乎相同。