繁体   English   中英

内存中异常的 Java 大小

[英]Java size of an Exception in memory

有谁知道异常在创建和抛出后占用多少内存?

例如, NullPointerException

异常是如何被垃圾收集的?

有谁知道异常在创建和抛出后占用多少内存?

这将完全取决于例外情况。 像任何其他对象一样,它包含可变数量的数据; 如果有人做了一些愚蠢的事情, String消息可能是 4MB:

Exception e = 
    new Exception(new String("Some gigantic message ... lalalalalalalalla"));

编辑:好的,这有点误导;异常包含对String的引用,并且引用值是固定大小,但String本身可能仅被异常引用 - 我将其更改为非文字以显式显示它可能是可收集的东西。尽管自定义异常可以包含任何内容,但它是一个与其他任何对象一样的对象。此外,这取决于它被抛出的距离,因为它在其中保存了堆栈跟踪。有一个很好的 Q/ A here on SO; 在 java 中,确定覆盖此对象的对象大小的最佳方法是什么。)

异常是如何被垃圾收集的?

就像任何其他对象一样。 异常被抛出调用堆栈,发生以下两种情况之一:

1)您捕获它,并将其分配给 catch 块中的一个变量:

catch (Exception e) {

e现在持有对异常的唯一引用。 当不再存在对它的引用时(即它超出了 catch 块底部的范围,或者您传递给它的对象被收集等),它将被收集。

2)你没有抓住它,它到达了当前线程的调用堆栈的顶部。 此时异常超出范围,因此将被收集,并且线程当然会停止。

** 为了完全迂腐,当我说“将被收集”时,我的意思是最终当 Java 中的对象不再有对其的引用时,它就有资格被收集,并且 GC 会处理它。

Java 异常是对象,因此任何其他对象的大小取决于它的结构,如果您创建了自定义异常,您可以(例如)存储完整的二进制文件其他对象,直到您有可用内存。 您可以为您的应用程序设置初始和最大空间。 可用空间动态变化,现在有 GC 问题。 Java 异常是对象,因此任何其他对象垃圾收集都使用环境中的规则。

有关异常的快速参考http://docs.oracle.com/javase/tutorial/essential/exceptions/

这是一篇关于垃圾收集的文章,其中的关键概念是

Java垃圾回收总结

1)Java Heap为了垃圾回收分为三代。 这些是年轻代,终身或老一代和彼尔姆地区。

2) 新对象被创建到年轻代,然后移动到老年代。

3) 字符串池创建在 Heap 的 Perm 区域,垃圾回收可以在 Perm 空间发生,但取决于 JVM 到 JVM。

4) Minor 垃圾回收用于将对象从 Eden 空间移动到 Survivor 1 和 Survivor 2 空间,Major 回收用于将对象从年轻代移动到年老代。

5) 每当发生主要垃圾收集时,应用程序线程都会在此期间停止,这将降低应用程序的性能和吞吐量。

6) java 6 中的垃圾收集几乎没有性能改进,我们通常使用 JRE 1.6.20 来运行我们的应用程序。

7) JVM 命令行选项 –Xmx 和 -Xms 用于设置 Java 堆的起始和最大大小。 根据我的经验,此参数的理想比率是 1:1 或 1:1.5,例如,您可以同时使用 –Xmx 和 –Xms 作为 1GB 或 –Xms 1.2 GB 和 1.8 GB。

8) 在 Java 中没有手动进行垃圾收集的方法。

阅读更多: http : //javarevisited.blogspot.it/2011/04/garbage-collection-in-java.html

如果你使用 java 7,一个关于 GC 的有趣问题是这个

Java 7 (JDK 7) 垃圾收集和 G1 上的文档

如果您需要调整应用程序的配置以使用 GC alg 终端内存,则其他建议非常有用,如果您只需要查看状态 bat。

这很容易自己找出来。 启动 jvisualvm 并附加到要分析的应用程序。 切换到内存选项卡并过滤您要查找的异常。

这应该可以让您很好地了解异常对象使用了多少字节 - 以及这与您的总堆大小之间的关系 - 以及它们被收集的程度和频率。

使用Java Mission Control进行检查。

在此处输入图片说明

我想知道为什么没有人提到创建异常时发生的第一件事是填充了堆栈跟踪:

 public Throwable() {
    fillInStackTrace();
 }

如果您创建自己的 Exception 类并覆盖fillInStackTrace()方法什么也不做,您的 Exception 将变成一个简单的 Java 对象,并且将占用与其他对象(具有相同的字段/值)一样多的内存。 但当然你会失去最宝贵的东西:堆栈跟踪。 综上所述,Exception 对象占用的内存大部分是由于存储堆栈跟踪(它以内部格式存储,然后在调用getStackTrace()方法时转换为StackTraceElement[] )。 所以堆栈跟踪越大,异常占用的内存就越多。

public class LightWeightException extends RuntimeException {

    public LightWeightException(String message) {
        super(message);
    }

    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM