保存实例变量

时间:2010-08-17 07:39:17

标签: java memory memory-management

我们的服务器最近一直在下降很多,我的任务是改善被确定为罪魁祸首的一组类的内存使用情况。

我有一个初始化对象实例的代码,如下所示:

布尔var1; 布尔var2; 。 。 。 boolean var100;

void setup() {
 var1 = map.hasFlag("var1");
 var2 = map.hasFlag("var2);
 .
 .
 .
 if (map.hasFlag("some flag") {
     doSomething();
 }
 if (var1) {
   increment something
 }
 if (var2) {
   increment something
 }

}

设置代码大约需要1300行。我的问题是,在使用太多实例变量方面,这种方法是否有可能更有效。

顺便说一下,实例变量用在“main”方法handleRow()中,例如:

handleRow(){
   if (var1) {
     doSomething();
   }
   .
   .
   . 
   if (var100) {
     doSomething();
    }
}

我想的一个解决方案是通过删除setup方法中的实例变量并在需要时直接从地图中调用它来更改实现:

handleRow(){
  if (map.hasFlag("var1") {
      doSomething();
  }
  .
  .
  . 
  if (map.hasFlag("var100") {
     doSomething();
  }
}

这是我正在考虑的一个解决方案,但我想听听社区的意见。 :)

4 个答案:

答案 0 :(得分:7)

如果这些都是boolean个变量,请考虑使用BitSet。您可能会发现,根据填充,内存占用量减少了8倍甚至32倍。

答案 1 :(得分:1)

您可以通过将值存储在位集中来节省内存(但如果您的内存使用是一个真正的问题,那么它可能是时间上的净增益)。

如果类是不可变的(一旦你创建它,你永远不会改变它),那么你可以通过在Flyweight模式上使用变体来获得。在这里,您可以在弱hashmap中存储正在使用的对象,并在工厂中创建对象。如果创建的对象与现有对象相同,则工厂将返回此前一个对象。根据有多少重复的物体,记忆中的节省可以忽略不计。

如果类不是不可变的,但是有这样的重复,你仍然可以使用Flyweight模式,但你必须做一种写时复制,其中改变一个对象使它从使用共享内部改变表示自己的一个(或来自flyweight商店的新表示)。这在时间上更复杂但更昂贵,但如果合适的话,节省的费用也会很高。

答案 2 :(得分:1)

您可以使用命令模式:

public enum Command {

    SAMPLE_FLAG1("FLAG1") {
        public abstract void call( ){
          //Do you increment here
        }
    },
    SAMPLE_FLAG2("FLAG2") {
        public abstract void call( ){
          //Do you increment here
        }
    };

    private Map<String, Command> commands = new HashMap<String, Command>( );

    static {
       for ( Command cmd : Command.values( )) {
           commands.put( cmd.name, cmd);
       }
    };



    private String name;
    private Command( String name) {
        this.name = name;
    }

    public Command fromString( String cmd) {
        return commands.get( cmd);
    }
    public abstract void call( ); 
}

然后:

for( String $ : flagMap.keySet( )) {
   Command.fromString( $).call( ); 
}

答案 3 :(得分:1)

当每个带有开销的布尔值占用16个字节时,100 boolean个变量将占用1.6k的内存(这有点不太可能)我认为这不会成为问题的根源。

通过调用地图取代这些标志会对性能产生负面影响,因此您的更改可能会使事情变得更糟。

在重新设计代码之前(命令模式看起来很合适),您应该进一步了解要求您解决的内存泄漏问题。

查找类不断添加的映射,静态变量集合等。一旦找到了内存增长的原因所在,就可以决定重构哪个类的部分。