您好!请问您能否解释一下,Exception或其子类的实例在内存中是如何分配的?它们是在堆栈中还是其他地方?
谢谢!
您好!请问您能否解释一下,Exception或其子类的实例在内存中是如何分配的?它们是在堆栈中还是其他地方?
谢谢!
public static void main(String... args) {
Throwable t = new Throwable("here");
System.out.println("Throwable before getStackTrace()");
shallowDump(t);
System.out.println("\nThrowable after getStackTrace()");
t.getStackTrace();
shallowDump(t);
}
private static void shallowDump(Object pojo) {
for (Field f : pojo.getClass().getDeclaredFields()) {
if (Modifier.isStatic(f.getModifiers())) continue;
f.setAccessible(true);
Object o;
try {
o = f.get(pojo);
if (o == pojo)
o = "{self}";
if (o instanceof Object[])
o = "Array of "+(o.getClass().getComponentType());
} catch (Exception e) {
o = e;
}
System.out.println(f.getName() + ": " + o);
}
}
打印
Throwable before getStackTrace()
detailMessage: here
cause: {self}
stackTrace: null
Throwable after getStackTrace()
detailMessage: here
cause: {self}
stackTrace: Array of class java.lang.StackTraceElement
System.gc();
for (int i = 0; i < 5; i++) {
Throwable[] ts = new Throwable[10000];
long free = Runtime.getRuntime().freeMemory();
for (int j = 0; j < ts.length; j++)
ts[j] = new Throwable();
long used = free - Runtime.getRuntime().freeMemory();
System.out.printf("Average Throwable size was %,d%n", used / ts.length);
}
System.gc();
for (int i = 0; i < 5; i++) {
Throwable[] ts = new Throwable[10000];
long free = Runtime.getRuntime().freeMemory();
for (int j = 0; j < ts.length; j++)
ts[j] = Throwable.class.newInstance();
long used = free - Runtime.getRuntime().freeMemory();
System.out.printf("Average Throwable.class.newInstance() size was %,d%n", used / ts.length);
}
使用反射获取当前方法中创建的Throwable对象和深层方法中创建的Throwable对象的大小(后者具有更深的堆栈)
Average Throwable size was 302
Average Throwable size was 302
Average Throwable size was 302
Average Throwable size was 302
Average Throwable size was 302
Average Throwable.class.newInstance() size was 247
Average Throwable.class.newInstance() size was 296
Average Throwable.class.newInstance() size was 296
Average Throwable.class.newInstance() size was 296
Average Throwable.class.newInstance() size was 296
Throwable的大小比您从它拥有的字段中所预期的要大得多。可以假设一些额外的信息被存储在堆上来帮助这个类,然而,如果所有的信息都存储在Throwable对象中,您会预期第二种类型的Throwable更大。
Exception
(以及所有的Throwable
)与 Java 中的任何其他对象一样。因此,它们会出现在堆中。正如 MusiKk 指出的那样,栈只能保存基本类型值或对象引用。
Throwable
的字段也是对象,所以它们无论如何都必须放在堆上,所以我想我没有完全考虑清楚。我会编辑一下。 - BoffinBrain它们在堆上创建,但这有什么关系呢?
Throwable
的字段也是对象,所以可能行不通。请看我的回答。 - BoffinBrain