子类化URI以清除其状态而不是创建新对象

时间:2016-12-11 00:23:09

标签: java

我们说我的代码是这样的:

URI u;

for (int i = 0; i < somenumber; i++) {

    u = new URI(...);

}

如果循环旋转了很多次迭代,对我来说通常超过200次,每次都会创建200个新对象,这是一个主要的内存泄漏。

你会说解决方案很容易,子类URI和实现clear(),对吗?

错误。它被宣布为最终决定。

怎么办?复制OpenJDK中的所有URI代码并使用它?

1 个答案:

答案 0 :(得分:2)

  

如果循环旋转了很多次迭代,对我来说通常超过200次,每次都会创建200个新对象,这是一个主要的内存泄漏。

从技术上讲,这不是内存泄漏。当GC无法回收对象时,会发生内存泄漏(使用Java)。

在您的示例中,URI引用的u对象在下一个循环迭代中变得无法访问。这意味着如果GC需要这样做,该对象几乎可以立即获得收集资格。 (除非你将堆大小设置为太小,否则它不会是必要的。)

在现代Java SE或Java EE JRE中,GC可以非常有效地回收短期垃圾对象。从(正常)性能角度来看,您的示例代码不会有问题。

  

你会说解决方案很简单,子类URI和实现clear(),对吧?错误。它被宣布为最终决定。

烨。 URI类被设计为不可变类。如果您可以创建子类,那么子类可以添加一个方法来使子类可变。这将使假设无效&#34;所有URI都是不可变的&#34;。

您提出的clear()方法正是这样做的。它使实例变得可变。

  

怎么办?复制OpenJDK中的所有URI代码并使用它?

这将是一种选择。其他人会:

  • 从头开始设计自己的URI课程。
  • 使用StringStringBuffer表示URI,并使用实用程序方法,正则表达式或其他方法解析它们。

但是,请注意解析URI(这很可能是您首先使用java.net.URI的原因)是:

  • 很复杂,因为涉及URI语法,
  • 可能会生成垃圾对象,除非您对实现很聪明。

在花费更多时间进行优化之前,我建议您使用Java分析器来确定为您的(完整)应用程序生成~200 URI个对象真正性能问题