Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java内存行为:与Thread.sleep不同_Java_Multithreading_Memory_Sleep_Behavior - Fatal编程技术网

Java内存行为:与Thread.sleep不同

Java内存行为:与Thread.sleep不同,java,multithreading,memory,sleep,behavior,Java,Multithreading,Memory,Sleep,Behavior,我试图用visualvm做一些记忆分析。 我已经编写了一个基本代码,运行无限循环将对象添加到列表中 package home.always.learning.java; import java.util.ArrayList; import java.util.List; public class Heaper { private static List<PersonDetails> listObj = new ArrayList<PersonDet

我试图用visualvm做一些记忆分析。 我已经编写了一个基本代码,运行无限循环将对象添加到列表中

package home.always.learning.java;  

import java.util.ArrayList;  
import java.util.List;  

public class Heaper {  

    private static List<PersonDetails> listObj = new ArrayList<PersonDetails>();  

    private static final String nameConst = "Tarun Trehan";  

    public static void main(String[] args)throws Exception{  
        personListCreation();  
    }  

    public static void personListCreation() throws Exception  
    {  
        int i = 0;  
        while(true)  
        {  
            System.out.println("Looping to create person list...");  
            i++;  
            listObj.add(new PersonDetails(nameConst+i));  
            //Thread.sleep(1000L);  
        }  
    }  
}  
记忆会增加,但随后会稳定下来并继续。请参阅随附的第二张快照,即内存稳定。JPG

我无法理解这种行为? 你能提供你的意见吗


有几件事值得考虑:

  • 这些人形尾巴物体有多大
  • 创建一个不是对象一部分的PersonDetail对象需要多少内存
第二个值可以是很多东西。数组列表每隔一段时间就会产生一些垃圾。创建字符串“nameConst+i”的过程将产生一些垃圾对象

假设答案是Persondeail很小,但制作一个Persondeail需要中等内存量。然后JVM将为您创建的每个PersonDetail扔掉一堆垃圾(垃圾收集)。在创建PersonDetails时,垃圾将堆积起来,最终JVM将收集垃圾。垃圾收集步骤将发现大量可用内存,因为大多数分配都是短期对象。这将产生一个类似于第二张图片中的图形,一个锯齿,其中内存被使用,然后大量垃圾被收集

现在假设您快速创建了一组对象(没有sleep语句)。现在,通过垃圾和列表中的对象,使用的总内存将快速增加。当您达到最大内存时,垃圾收集将不得不更频繁地发生。有点像上面的图表


我不确定这是怎么回事,但你可以做一件事来观察它,就是观察VisualVM中的采样,看看类创建了多少对象,更重要的是它们占用了多少内存。将PersonDetails使用的数量与其他垃圾进行比较,以便在需要时进行清理。

查看稍微修改过的代码版本(固定的迭代次数,在启动后添加5s暂停以允许我的IDE连接到visualvm,删除system.out.print以提高速度等)看来你的罪魁祸首是垃圾收集:

100升睡眠:(跑了5:18)

有10L睡眠:(跑了5:01)

带2升睡眠:(跑了4:57)

有1L睡眠:(跑6:36)

使用0L睡眠:(运行时间为0:23)


因此,我们基本上发现,使用的堆将缓慢上升,直到填满Eden空间(导致分配失败),将Eden的较老成员(几乎所有成员,从空间使用情况来看)移动到幸存者0/1,睡眠和不睡眠之间的区别很可能是次要集合和主要集合的相对频率之间的差异。

比较相同循环迭代次数(而不是相同时间长度)的行为。显然,它会慢得多,但是存档同样的效果。谢谢你的输入。将尝试发布更新。再次感谢。嗨,我能通过线程观察到记忆的增加。睡眠到位。正如正确指出的,增长的速度是缓慢的,但行为和内存占用最终将是相同的。谢谢
Thread.sleep(1000L);