代码之家  ›  专栏  ›  技术社区  ›  Dani Cricco

Java非请求内存分配

  •  1
  • Dani Cricco  · 技术社区  · 16 年前

    在jconsole下观察到的下面一段代码显示堆大小不断增加。堆最大可达25MB,然后GC运行并将堆大小减小到接近3MB。这是预期的行为吗?我很惊讶!

    public class Dummy {
        public static void main(String[] args) {
            System.out.println("start");
            while(true){
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    我在用雪豹。

    5 回复  |  直到 16 年前
        1
  •  8
  •   Dana the Sane    16 年前

    与jconsole通信会导致对象被分配。我相信你在这里看到的是你测量方法的产物。编译代码时,也可能会按热点进行少量分配。如果您担心,请使用探查器查看正在分配的内容(再次注意探查器接口的分配)。

    正常的gc行为是为了避免不必要地运行。你会在网络上看到所有关于内存使用的锯齿形图。在缓存和交换友好性和避免工作之间有一些折衷。此外,服务器热点在耗尽内存方面比客户端热点更为激进。

        2
  •  4
  •   Paul Wagland    16 年前

    是的,这应该是预期的行为。虽然您没有做任何特定的分配对象的操作,但是sleep的实现可能是,即使没有,jvm中也可能运行其他线程。

        3
  •  3
  •   Wyzard    16 年前

    是的,这很正常。您没有显式地创建任何对象,但调用的方法可能会创建一些临时对象作为其实现的一部分。这些临时对象会堆积起来,直到gc运行时清除它们。

        4
  •  2
  •   stacker    16 年前

    类文件看起来是这样的,代码从8循环到14,java.lang.thread.sleep()是本机的。因此没有理由创建MB的对象

     public static void main(java.lang.String[] args);
         0  getstatic java.lang.System.out : java.io.PrintStream [16]
         3  ldc <String "start"> [22]
         5  invokevirtual java.io.PrintStream.println(java.lang.String) : void [24]
         8  ldc2_w <Long 5000> [30]
        11  invokestatic java.lang.Thread.sleep(long) : void [32]
        14  goto 8
        17  astore_1 [e]
        18  aload_1 [e]
        19  invokevirtual java.lang.InterruptedException.printStackTrace() : void [38]
        22  goto 8
    

    恐怕您看到的是jprofiler本身(我不知道您是如何将它附加到您的虚拟测试应用程序上的)或运行在这个vm中的其他东西。如果jprofiler不显示此信息,则应执行堆转储以了解创建了哪些对象。

    '

        5
  •  1
  •   Stephen C    16 年前

    关于原因,显然有两种理论,基于经验推理是不可能区分它们的。我能建议一个简单的实验吗?

    1. 将程序更改为睡眠1毫秒而不是5000秒。(实际数字无关紧要……这是为了使假设的内存分配尽可能快地发生。您也可以尝试0毫秒,但睡眠的行为可能会有所不同…)

    2. 使用当前方法运行程序;例如使用jconsole。

    3. 不使用jconsole等运行程序,但使用“-verbose:gc”选项,这样您就可以看到gc何时运行。

    我怀疑你等着GC在最后一个案子中运行时会失去耐心…甚至呼叫 sleep 尽快。

    推荐文章