Java对象分配开销

Java对象分配开销,java,xml,dom,concurrency,Java,Xml,Dom,Concurrency,我正在用Java编写一个不可变的DOM树,以简化多线程的访问* 但是,它确实需要尽可能快地支持插入和更新。由于它是不可变的,如果我对树的第N级上的节点进行更改,我需要分配至少N个新节点以返回新树 我的问题是,每次修改树时,预分配节点会比创建新节点快得多吗?这相当容易做到——保留一个包含数百个未使用节点的池,并在修改操作需要时从池中拉出一个节点,而不是创建一个节点。我可以在没有其他事情发生时补充节点池。(如果不是很明显,那么在这个应用程序中,执行时间比堆空间要贵得多) 这样做值得吗?还有其他加快速

我正在用Java编写一个不可变的DOM树,以简化多线程的访问*

但是,它确实需要尽可能快地支持插入和更新。由于它是不可变的,如果我对树的第N级上的节点进行更改,我需要分配至少N个新节点以返回新树

我的问题是,每次修改树时,预分配节点会比创建新节点快得多吗?这相当容易做到——保留一个包含数百个未使用节点的池,并在修改操作需要时从池中拉出一个节点,而不是创建一个节点。我可以在没有其他事情发生时补充节点池。(如果不是很明显,那么在这个应用程序中,执行时间比堆空间要贵得多)

这样做值得吗?还有其他加快速度的建议吗

或者,有人知道不可变DOM库是否已经存在吗?我找了,但什么也没找到


*注意:对于那些不熟悉不变性概念的人来说,它基本上意味着在对某个对象进行任何更改的操作时,该方法都会返回该对象的一个副本,其中包含更改,而不是已更改的对象。因此,如果另一个线程仍在读取该对象,它将继续在“旧”版本上愉快地运行,而不知道已经进行了更改,而不是可怕地崩溃。请参见

我不想给出一个不确定的答案,但我认为回答这样一个性能问题的唯一确定方法可能是对这两种方法进行编码,对它们进行基准测试,并比较结果。

如今,对象创建速度非常快,对象池的概念有点过时(至少在一般情况下;连接池当然仍然有效)


避免过早的优化。在进行复制时,在需要节点时创建节点,然后查看其速度是否会变得异常缓慢。如果是这样,请研究一些技术来加快优化速度。但是,除非您已经知道现有的速度不够快,否则我不会介绍实现池化所需的所有复杂性继续。

我对您首先要做的事情有点困惑。您希望所有节点都是不可变的,并且希望将它们合并在一起?这两个想法不是相互排斥的吗?当您从池中拉出一个对象时,您不需要调用setter来链接子节点吗

我认为,使用不可变节点可能不会给您提供您首先需要的线程安全性,而另一个线程正在添加/删除节点?搜索结果是否无效?我不确定是否可以避免显式同步某些方法,以确保所有内容都是线程安全的。

当你把一个物体拉出 pool,你不需要调用 塞特把孩子们联系起来

每个节点不必在包的内部是不可变的,只对外向接口是不可变的。
node.addChild()
将是一个具有公共可见性的不可变函数,并返回一个文档,wheras
node.addChildInternal()
将是一个正常的、可变的函数,具有包可见性。但由于它是包的内部函数,因此只能作为
addChild()
的后代调用它,并且整个结构被保证是线程安全的(前提是我同步访问对象池)。您是否看到这方面的缺陷…?如果是,请告诉我

我认为使用不可变节点可能不会首先为您提供所需的线程安全性。如果一个线程在节点上迭代(搜索或其他),而另一个线程正在添加/删除节点,会发生什么情况

树作为一个整体是不可变的。假设我有Thread1和Thread2,树dom1。Thread1在dom1上启动读取操作,同时Thread2在dom1上启动写入操作。但是,Thread2所做的所有更改实际上都将对新对象dom2和dom1进行修改。Thread1读取的值确实是不可变的我将(几微秒)过期,但它不会在IndexOutOfBounds或NullPointer异常上崩溃,或者在读取正在写入的可变对象时崩溃。然后,Thread2可以向Thread1触发一个包含dom2的事件,以便它可以再次读取并在必要时更新其结果


编辑:澄清

我认为@Outlaw有一点。DOM树的结构存在于节点本身,有一个节点指向其子节点。要修改树的结构,必须修改节点,因此不能将其合并,必须创建一个新的节点

试着从更高的层次思考。你有一个不可变的树(基本上是一组指向其子节点的节点)。你想在其中插入一个节点。然后,没有出路:你必须创建一个新的整棵树

是的,不可变树是线程安全的,但它会影响性能。对象创建可能很快,但不会比不创建对象快。:)

我不确定是否可以避免显式同步某些方法,以确保一切都是线程安全的

在一种特定情况下,您需要同步使新创建的节点可供其他线程使用的一方或另一方,否则可能会导致VM/CPU在将引用写入共享节点之后重新排序字段的写入,从而公开参与方构造的对象

试着从更高的层次思考。您有一个不可变的树(基本上是一组指向其子节点的节点)。您想在其中插入一个节点。然后,就没有出路了:你必须创建一棵新的整棵树

如果选择将树实现为指向子节点的一组节点,则必须创建