简单类 - 它是一个内存泄漏? [英] Simple Class - Is it a Memory Leak?

查看:121
本文介绍了简单类 - 它是一个内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的类,它有一个整数变量。我只是将变量'i'的值打印到屏幕上并递增它,并使线程休眠1秒钟。当我针对此方法运行探查器时,即使我没有创建任何新变量,内存使用量也会缓慢增加。执行此代码大约16个小时后,我发现内存使用量已增加到4 MB(当我启动程序时,最初为1 MB)。我是Java的新手。有没有人可以帮助解释我哪里出错了,或者为什么即使没有创建新变量,内存使用量也会逐渐增加?提前致谢。

I've a very simple class which has one integer variable. I just print the value of variable 'i' to the screen and increment it, and make the thread sleep for 1 second. When I run a profiler against this method, the memory usage increases slowly even though I'm not creating any new variables. After executing this code for around 16 hours, I see that the memory usage had increased to 4 MB (initially 1 MB when I started the program). I'm a novice in Java. Could any one please help explain where am I going wrong, or why the memory usage is gradually increasing even when there are no new variables created? Thanks in advance.

我正在使用netbeans 7.1及其分析器查看内存使用情况。

I'm using netbeans 7.1 and its profiler to view the memory usage.

    public static void main(String[] args)
    {
        try
        {
            int i = 1;
            while(true)
            {
                System.out.println(i);
                i++;
                Thread.sleep(1000);
            }
        }
        catch(InterruptedException ex)
        {
            System.out.print(ex.toString());
        }
    }

程序启动时的初始内存使用情况:1569852字节。

Initial memory usage when the program started : 1569852 Bytes.

执行循环16小时后的内存使用情况:4095829字节

Memory usage after executing the loop for 16 hours : 4095829 Bytes

推荐答案

它不一定是内存泄漏。 GC运行时,将收集 System.out.println(i); 语句中分配的对象(我假设)。 Java中的内存泄漏是当内存填满无法通过GC无法回收的无用对象时。

It is not necessarily a memory leak. When the GC runs, the objects that are allocated (I presume) in the System.out.println(i); statement will be collected. A memory leak in Java is when memory fills up with useless objects that can't be reclaimed by the GC.

println(i)正在使用 Integer.toString(int) int 转换为String,并且每次都分配一个新的 String 。这不是泄漏,因为String一旦被复制到输出缓冲区就会变得无法访问并成为GC的候选者。

The println(i) is using Integer.toString(int) to convert the int to a String, and that is allocating a new String each time. That is not a leak, because the String will become unreachable and a candidate for GC'ing once it has been copied to the output buffer.

其他可能的内存分配来源:

Other possible sources of memory allocation:


  • Thread.sleep可能会分配对象。

  • Thread.sleep could be allocating objects under the covers.

某些私有JVM线程可能导致此问题。

Some private JVM thread could be causing this.

探查器用于监视JVM状态的java代理代码可能是导致这个。它必须通过套接字将数据汇编并发送到探查器应用程序,这很可能涉及分配Java对象。它也可能在JVM的堆或非堆内存中累积内容。

The "java agent" code that the profiler is using to monitor the JVM state could be causing this. It has to assemble and send data over a socket to the profiler application, and that could well involve allocating Java objects. It may also be accumulating stuff in the JVM's heap or non-heap memory.

但这并不重要只要在运行GC的情况下,可以回收空间。如果它不能,那么您可能在您正在使用的探查器中发现了JVM错误或错误。 (尝试用一个非常长的睡眠来替换循环并查看泄漏是否仍然存在。)并且如果这是由分析引起的缓慢泄漏可能无关紧要...因为您通常不运行生产代码启用该分析的分析。

But it doesn't really matter so long as the space can be reclaimed if / when the GC runs. If it can't, then you may have found a JVM bug or a bug in the profiler that you are using. (Try replacing the loop with one very long sleep and see if the "leak" is still there.) And it probably doesn't matter if this is a slow leak caused by profiling ... because you don't normally run production code with profiling enabled for that long.

注意:调用 System.gc()不保证会导致GC运行。阅读javadoc。

Note: calling System.gc() is not guaranteed to cause the GC to run. Read the javadoc.

这篇关于简单类 - 它是一个内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆