[科研小记]在Java中的内存溢出问题

09 Mar 2020

最近在重新编写仿真平台时,发现程序运行时的内存占用从开始的300M一路飙升到7G,重新检查新写的代码,在以下对HashMap进行操作的时候会发生内存溢出的问题:

  private HashMap<DTNHost, List<Double>> channelStatusRecord = new HashMap<DTNHost, List<Double>>();
  private void connectionUpdate(){
    for (Connection con : getConnections()) {
      con.update();
      double currentSpeed = con.getSpeed();
      DTNHost otherNode = con.getOtherNode(this.getHost());
      List<Double> record = this.channelStatusRecord.get(otherNode);
      if (record == null)
        record = new ArrayList<Double>();
      record.add(currentSpeed);
      this.channelStatusRecord.put(otherNode, record);
    }
  }


当执行最后一行代码时,会造成内存占用大幅度增加,在修改代码的过程中,在参考了网上教程后,一开始觉得这里可能是因为channelStatusRecord这一HashMap初始化时的key和value皆为null,每次我将record = new ArrayList()重新put回去时,会造成hashcode的改变,进而每次无法释放HashMap里的对ArrayList的引用,造成重复内存占用。
结果后来才发现是我自己太蠢了,因为这里的list会随着运行时间的增大而不断变大,每一个Node下都对应一个随时间不断增长的list,用于存储channel state, 而实际上这些历史信息并不是必须的。所以只需要设置一个阈值,当list大小大于一定值时,清空list即可。这样内存占用问题即迎刃而解。