简体   繁体   English

内存中异常的 Java 大小

[英]Java size of an Exception in memory

Does anyone know how much memory an Exception occupies once it is created and thrown ?有谁知道异常在创建和抛出后占用多少内存?

For example, NullPointerException .例如, NullPointerException

And how exceptions are being garbage collected?异常是如何被垃圾收集的?

Does anyone know how much memory an Exception occupies once it is created and thrown?有谁知道异常在创建和抛出后占用多少内存?

That would depend entirely on the exception.这将完全取决于例外情况。 Like any other object, it contains variable amount of data;像任何其他对象一样,它包含可变数量的数据; the String message could be 4MB if someone did something silly:如果有人做了一些愚蠢的事情, String消息可能是 4MB:

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

( Edit: ok, this is somewhat misleading; the exception contains a reference to a String and reference values are a fixed size, but the String itself might only be referenced by the exception - I changed it to be a non-literal to explicitly show it could be something that is collectible. A custom exception could hold anything though, it's an object like any other. In addition, it depends how far it has been thrown, since it holds the stack trace inside of it. There's a good Q/A here on SO; In java, what is the best way to determine the size of an object that covers this. ) 编辑:好的,这有点误导;异常包含对String的引用,并且引用值是固定大小,但String本身可能仅被异常引用 - 我将其更改为非文字以显式显示它可能是可收集的东西。尽管自定义异常可以包含任何内容,但它是一个与其他任何对象一样的对象。此外,这取决于它被抛出的距离,因为它在其中保存了堆栈跟踪。有一个很好的 Q/ A here on SO; 在 java 中,确定覆盖此对象的对象大小的最佳方法是什么。)

And how exceptions are being garbage collected?异常是如何被垃圾收集的?

Just as any other object is.就像任何其他对象一样。 The Exception is thrown up the call stack and one of two things happen:异常被抛出调用堆栈,发生以下两种情况之一:

1) You catch it, and it's assigned to a variable in the catch block: 1)您捕获它,并将其分配给 catch 块中的一个变量:

catch (Exception e) {

e now holds the one and only reference to the exception. e现在持有对异常的唯一引用。 When no more references to it exist (ie it either falls out of scope at the bottom of the catch block, or the object you pass it to gets collected, etc), it will get collected.当不再存在对它的引用时(即它超出了 catch 块底部的范围,或者您传递给它的对象被收集等),它将被收集。

2) You don't catch it and it hits the top of the call stack for the current thread. 2)你没有抓住它,它到达了当前线程的调用堆栈的顶部。 At that point the exception falls out of scope so it will be collected, and the thread is of course halted.此时异常超出范围,因此将被收集,并且线程当然会停止。

** To be completely pedantic when I say "will get collected" I mean eventually as when an object in Java has no more references to it it's it's eligible for collection, and the GC deals with it. ** 为了完全迂腐,当我说“将被收集”时,我的意思是最终当 Java 中的对象不再有对其的引用时,它就有资格被收集,并且 GC 会处理它。

Java Exceptions are Object so as any Other Objects the size depends by it structure if you have created a custom exception you can (for example) store e complete binary file other Object until you have free memory. Java 异常是对象,因此任何其他对象的大小取决于它的结构,如果您创建了自定义异常,您可以(例如)存储完整的二进制文件其他对象,直到您有可用内存。 You can set the initial and maximum space for your application.您可以为您的应用程序设置初始和最大空间。 The free space change dynamically and now there is the GC question.可用空间动态变化,现在有 GC 问题。 Java Exceptions are Object so as any Other Objects garbage collection uses the rules in your Enviorment. Java 异常是对象,因此任何其他对象垃圾收集都使用环境中的规则。

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

this is an article about garbage collection where the key concept are这是一篇关于垃圾收集的文章,其中的关键概念是

Summary on Garbage collection in Java Java垃圾回收总结

1) Java Heap is divided into three generation for sake of garbage collection. 1)Java Heap为了垃圾回收分为三代。 These are young generation, tenured or old generation and Perm area.这些是年轻代,终身或老一代和彼尔姆地区。

2) New objects are created into young generation and subsequently moved to old generation. 2) 新对象被创建到年轻代,然后移动到老年代。

3) String pool is created in Perm area of Heap, garbage collection can occur in perm space but depends upon JVM to JVM. 3) 字符串池创建在 Heap 的 Perm 区域,垃圾回收可以在 Perm 空间发生,但取决于 JVM 到 JVM。

4) Minor garbage collection is used to move object from Eden space to Survivor 1 and Survivor 2 space and Major collection is used to move object from young to tenured generation. 4) Minor 垃圾回收用于将对象从 Eden 空间移动到 Survivor 1 和 Survivor 2 空间,Major 回收用于将对象从年轻代移动到年老代。

5) Whenever Major garbage collection occurs application threads stops during that period which will reduce application's performance and throughput. 5) 每当发生主要垃圾收集时,应用程序线程都会在此期间停止,这将降低应用程序的性能和吞吐量。

6) There are few performance improvement has been applied in garbage collection in java 6 and we usually use JRE 1.6.20 for running our application. 6) java 6 中的垃圾收集几乎没有性能改进,我们通常使用 JRE 1.6.20 来运行我们的应用程序。

7) JVM command line options –Xmx and -Xms is used to setup starting and max size for Java Heap. 7) JVM 命令行选项 –Xmx 和 -Xms 用于设置 Java 堆的起始和最大大小。 Ideal ratio of this parameter is either 1:1 or 1:1.5 based upon my experience for example you can have either both –Xmx and –Xms as 1GB or –Xms 1.2 GB and 1.8 GB.根据我的经验,此参数的理想比率是 1:1 或 1:1.5,例如,您可以同时使用 –Xmx 和 –Xms 作为 1GB 或 –Xms 1.2 GB 和 1.8 GB。

8) There is no manual way of doing garbage collection in Java. 8) 在 Java 中没有手动进行垃圾收集的方法。

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

If you use java 7 an intersting question about GC is this如果你使用 java 7,一个关于 GC 的有趣问题是这个

Java 7 (JDK 7) garbage collection and documentation on G1 Java 7 (JDK 7) 垃圾收集和 G1 上的文档

Other suggestion are useful if you need to view only the state bat if you need to tune the config of your app you need to work with GC alg end memory.如果您需要调整应用程序的配置以使用 GC alg 终端内存,则其他建议非常有用,如果您只需要查看状态 bat。

Thats easy to find out by yourself.这很容易自己找出来。 Launch jvisualvm and attach to the application you want to profile.启动 jvisualvm 并附加到要分析的应用程序。 Switch to the memory tab and filter for the exception you are looking for.切换到内存选项卡并过滤您要查找的异常。

That should give you a good picture of how many bytes are used by exception objects - and also how this relates to your total heap size - and how well and how often they get collected.这应该可以让您很好地了解异常对象使用了多少字节 - 以及这与您的总堆大小之间的关系 - 以及它们被收集的程度和频率。

Use Java Mission Control for checking this.使用Java Mission Control进行检查。

在此处输入图片说明

I'm wondering why nobody mentioned that the first thing which happens when you create an exception is that the stack trace is populated:我想知道为什么没有人提到创建异常时发生的第一件事是填充了堆栈跟踪:

 public Throwable() {
    fillInStackTrace();
 }

If you create your own Exception class and override the fillInStackTrace() method to do nothing, your Exception will become just a simple Java Object and will occupy just as much memory as other objects (which have the same fields/values).如果您创建自己的 Exception 类并覆盖fillInStackTrace()方法什么也不做,您的 Exception 将变成一个简单的 Java 对象,并且将占用与其他对象(具有相同的字段/值)一样多的内存。 But of course you will lose the most precious thing: the stack trace.但当然你会失去最宝贵的东西:堆栈跟踪。 As a conclusion, most of the memory occupied by the Exception object is due to storing the stack trace (it is stored in an internal format, then converted to StackTraceElement[] when the getStackTrace() method is called).综上所述,Exception 对象占用的内存大部分是由于存储堆栈跟踪(它以内部格式存储,然后在调用getStackTrace()方法时转换为StackTraceElement[] )。 So the larger the stack trace, the more memory the exception will occupy.所以堆栈跟踪越大,异常占用的内存就越多。

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