<!-- 
RSS generated by JIRA (8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d) at Wed Feb 07 19:56:40 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>OpenDaylight JIRA</title>
    <link>https://jira.opendaylight.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>8.20.10</version>
        <build-number>820010</build-number>
        <build-date>22-06-2022</build-date>
    </build-info>


<item>
            <title>[CONTROLLER-1872] Excessive byte array copy in Akka</title>
                <link>https://jira.opendaylight.org/browse/CONTROLLER-1872</link>
                <project id="10113" key="CONTROLLER">controller</project>
                    <description>&lt;p&gt;One of the very top &quot;TLAB allocation&quot; (cumulative many 10s of GiBs - that&apos;s a hell of a lot, no?) observed in a JFR from internal scale testing, which seems to contributed to excessive GC, is the code path below.  &lt;/p&gt;

&lt;p&gt;Is this just &quot;too bad&quot; and &quot;simply the way Akka has to work&quot; and we accept this, or is there any way that we could (get Akka to / work with) to have this optimized to cause less object allocation?&lt;/p&gt;

&lt;p&gt;There are actually 2 distincts paths, the first bigger one is:&lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] java.util.Arrays.copyOf(&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[], &lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;)	55539
void java.io.ByteArrayOutputStream.grow(&lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;)	37343
void java.io.ByteArrayOutputStream.ensureCapacity(&lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;)	37343
void java.io.ByteArrayOutputStream.write(&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[], &lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;)	37343
void java.io.ObjectOutputStream$BlockDataOutputStream.write(&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[], &lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt;)	27262
void java.io.ObjectOutputStream.write(&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[])	27262
void org.opendaylight.controller.cluster.datastore.persisted.CommitTransactionPayload$Proxy.writeExternal(ObjectOutput)	27262
void java.io.ObjectOutputStream.writeExternalData(Externalizable)	27262
void java.io.ObjectOutputStream.writeOrdinaryObject(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, ObjectStreamClass, &lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt;)	27262
void java.io.ObjectOutputStream.writeObject0(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt;)	27262
void java.io.ObjectOutputStream.writeObject(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
void org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry$Proxy.writeExternal(ObjectOutput)	27262
void java.io.ObjectOutputStream.writeExternalData(Externalizable)	27262
void java.io.ObjectOutputStream.writeOrdinaryObject(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, ObjectStreamClass, &lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt;)	27262
void java.io.ObjectOutputStream.writeObject0(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt;)	27262
void java.io.ObjectOutputStream.writeObject(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
void akka.serialization.JavaSerializer.$anonfun$toBinary$1(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, ObjectOutputStream)	27262
void akka.serialization.JavaSerializer$$Lambda$862.398419640.apply$mcV$sp()	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.runtime.java8.JFunction0$mcV$sp.apply()	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.util.DynamicVariable.withValue(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, Function0)	27262
&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] akka.serialization.JavaSerializer.toBinary(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
MessageFormats$PersistentPayload$Builder akka.persistence.serialization.MessageSerializer.payloadBuilder$1(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
MessageFormats$PersistentPayload$Builder akka.persistence.serialization.MessageSerializer.$anonfun$persistentPayloadBuilder$1(MessageSerializer, &lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.serialization.MessageSerializer$$Lambda$878.273383069.apply()	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.util.DynamicVariable.withValue(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, Function0)	27262
MessageFormats$PersistentPayload$Builder akka.persistence.serialization.MessageSerializer.persistentPayloadBuilder(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
MessageFormats$PersistentMessage$Builder akka.persistence.serialization.MessageSerializer.persistentMessageBuilder(PersistentRepr)	27262
&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] akka.persistence.serialization.MessageSerializer.toBinary(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] akka.serialization.Serialization.$anonfun$serialize$1(Serialization, &lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.serialization.Serialization$$Lambda$877.275215371.apply()	27262
Try scala.util.Try$.apply(Function0)	27262
Try akka.serialization.Serialization.serialize(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] akka.persistence.journal.leveldb.LeveldbStore.persistentToBytes(PersistentRepr)	27262
&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] akka.persistence.journal.leveldb.LeveldbStore.persistentToBytes$(LeveldbStore, PersistentRepr)	27262
&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] akka.persistence.journal.leveldb.LeveldbJournal.persistentToBytes(PersistentRepr)	27262
void akka.persistence.journal.leveldb.LeveldbStore.addToMessageBatch(PersistentRepr, Set, WriteBatch)	27262
void akka.persistence.journal.leveldb.LeveldbStore.$anonfun$asyncWriteMessages$5(LeveldbStore, ObjectRef, WriteBatch, PersistentRepr)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbStore.$anonfun$asyncWriteMessages$5$adapted(LeveldbStore, ObjectRef, WriteBatch, PersistentRepr)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbStore$$Lambda$875.1221692884.apply(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
void scala.collection.immutable.List.foreach(Function1)	27262
void akka.persistence.journal.leveldb.LeveldbStore.$anonfun$asyncWriteMessages$4(LeveldbStore, ObjectRef, ObjectRef, WriteBatch, AtomicWrite)	27262
void akka.persistence.journal.leveldb.LeveldbStore$$Lambda$874.735864755.apply$mcV$sp()	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.runtime.java8.JFunction0$mcV$sp.apply()	27262
Try scala.util.Try$.apply(Function0)	27262
Try akka.persistence.journal.leveldb.LeveldbStore.$anonfun$asyncWriteMessages$3(LeveldbStore, ObjectRef, ObjectRef, WriteBatch, AtomicWrite)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbStore$$Lambda$873.510803830.apply(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
Builder scala.collection.TraversableLike.$anonfun$map$1(Function1, Builder, &lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.collection.TraversableLike$$Lambda$283.599282230.apply(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
void scala.collection.Iterator.foreach(Function1)	27262
void scala.collection.Iterator.foreach$(Iterator, Function1)	27262
void scala.collection.AbstractIterator.foreach(Function1)	27262
void scala.collection.IterableLike.foreach(Function1)	27262
void scala.collection.IterableLike.foreach$(IterableLike, Function1)	27262
void scala.collection.AbstractIterable.foreach(Function1)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.collection.TraversableLike.map(Function1, CanBuildFrom)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.collection.TraversableLike.map$(TraversableLike, Function1, CanBuildFrom)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; scala.collection.AbstractTraversable.map(Function1, CanBuildFrom)	27262
Seq akka.persistence.journal.leveldb.LeveldbStore.$anonfun$asyncWriteMessages$2(LeveldbStore, Seq, ObjectRef, ObjectRef, WriteBatch)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbStore$$Lambda$872.1336396232.apply(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbStore.withBatch(Function1)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbStore.withBatch$(LeveldbStore, Function1)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbJournal.withBatch(Function1)	27262
Seq akka.persistence.journal.leveldb.LeveldbStore.$anonfun$asyncWriteMessages$1(LeveldbStore, Seq, ObjectRef, ObjectRef)	27262
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.persistence.journal.leveldb.LeveldbStore$$Lambda$871.1879377751.apply()	27262&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The other one is:&lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;&lt;span class=&quot;code-object&quot;&gt;byte&lt;/span&gt;[] akka.protobuf.AbstractMessageLite.toByteArray()	27218
ByteString akka.remote.transport.AkkaPduProtobufCodec$.constructPayload(ByteString)	9987
&lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt; akka.remote.transport.AkkaProtocolHandle.write(ByteString)	9987
&lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt; akka.remote.EndpointWriter.writeSend(EndpointManager$Send)	9987
&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; akka.remote.EndpointWriter$$anonfun$4.applyOrElse(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;, Function1)	9975
void akka.actor.Actor.aroundReceive(PartialFunction, &lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	9975
void akka.actor.Actor.aroundReceive$(Actor, PartialFunction, &lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	9975
void akka.remote.EndpointActor.aroundReceive(PartialFunction, &lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	9975
void akka.actor.ActorCell.receiveMessage(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt;)	9975
void akka.actor.ActorCell.invoke(Envelope)	9975
void akka.dispatch.Mailbox.processMailbox(&lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt;, &lt;span class=&quot;code-object&quot;&gt;long&lt;/span&gt;)	9975
void akka.dispatch.Mailbox.run()	9975
&lt;span class=&quot;code-object&quot;&gt;boolean&lt;/span&gt; akka.dispatch.Mailbox.exec()	9975
&lt;span class=&quot;code-object&quot;&gt;int&lt;/span&gt; akka.dispatch.forkjoin.ForkJoinTask.doExec()	9975
void akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinTask)	9975
void akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool$WorkQueue)	9975
void akka.dispatch.forkjoin.ForkJoinWorkerThread.run()	9975&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</description>
                <environment></environment>
        <key id="31019">CONTROLLER-1872</key>
            <summary>Excessive byte array copy in Akka</summary>
                <type id="10104" iconUrl="https://jira.opendaylight.org/secure/viewavatar?size=xsmall&amp;avatarId=10303&amp;avatarType=issuetype">Bug</type>
                                            <priority id="3" iconUrl="https://jira.opendaylight.org/images/icons/priorities/major.svg">Medium</priority>
                        <status id="5" iconUrl="https://jira.opendaylight.org/images/icons/statuses/resolved.png" description="A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.">Resolved</status>
                    <statusCategory id="3" key="done" colorName="green"/>
                                    <resolution id="10000">Done</resolution>
                                        <assignee username="tpantelis">Tom Pantelis</assignee>
                                    <reporter username="vorburger">Michael Vorburger</reporter>
                        <labels>
                    </labels>
                <created>Tue, 13 Nov 2018 13:24:17 +0000</created>
                <updated>Tue, 4 Dec 2018 15:32:49 +0000</updated>
                            <resolved>Tue, 4 Dec 2018 15:32:49 +0000</resolved>
                                    <version>Oxygen SR3</version>
                                    <fixVersion>Neon</fixVersion>
                    <fixVersion>Fluorine SR2</fixVersion>
                                        <due></due>
                            <votes>0</votes>
                                    <watches>2</watches>
                                                                                                                <comments>
                            <comment id="65628" author="rovarga" created="Wed, 14 Nov 2018 13:03:07 +0000"  >&lt;p&gt;These are normal &#8211; we cannot know the final size of the allocation until we have traversed the object. Doing a two-phase traversal wastes CPU cycles &lt;b&gt;more&lt;/b&gt; than the incurrect GC/copies, which use exponential resize.&lt;/p&gt;</comment>
                            <comment id="65695" author="tpantelis" created="Fri, 16 Nov 2018 15:11:30 +0000"  >&lt;p&gt;It would eliminate some re-allocations if JavaSerializer.toBinary specified a larger initial size to the ByteArrayOutputStream. The is similar to &lt;a href=&quot;https://jira.opendaylight.org/browse/CONTROLLER-1870&quot; title=&quot;Excessive Arrays.copyOf memory allocation from AbstractNormalizedNodeDataOutput&quot; class=&quot;issue-link&quot; data-issue-key=&quot;CONTROLLER-1870&quot;&gt;&lt;del&gt;CONTROLLER-1870&lt;/del&gt;&lt;/a&gt;. We could hook in our own serializer for SimpleReplicatedLogEntry that does that. The nice part is that we can estimate the serialized size very closely via Payload.size().&lt;/p&gt;</comment>
                            <comment id="65868" author="tpantelis" created="Mon, 3 Dec 2018 18:47:34 +0000"  >&lt;p&gt;Submitted &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/78390/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/78390/&lt;/a&gt;&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                            <customfield id="customfield_11400" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10000" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|i03kfb:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                </customfields>
    </item>
</channel>
</rss>