----------------------------------------------------------- This is an automatically generated e-mail. To reply, visit: https://reviews.apache.org/r/72666/#review221333 -----------------------------------------------------------
intg/src/main/java/org/apache/atlas/utils/FixedBufferList.java Lines 51 (patched) <https://reviews.apache.org/r/72666/#comment310221> this assumes that the elements are accessed in ascending oeder - since getAndIncrementLength() simply increments the length by 1. I suggest to get rid of getAndIncrementLength() and update getForUpdate() as below: public T getForUpdate(int index) { ensureCapacity(index + 1); T ret = buffer.get(index); // update length only if the accessed index is beyond the current length if (this.length <= index) { this.length = index + 1; } return ret; } intg/src/main/java/org/apache/atlas/utils/FixedBufferList.java Lines 55 (patched) <https://reviews.apache.org/r/72666/#comment310223> To make it easier to read, I suggest to get rid of method resetCurrentLength() and update toList() as below: public List<T> toList(boolean resetList) { List<T> ret = this.buffer.subList(0, this.length); if (resetList) { this.length = 0; } } intg/src/main/java/org/apache/atlas/utils/FixedBufferList.java Lines 60 (patched) <https://reviews.apache.org/r/72666/#comment310226> - is 'incrementCapacityBy' argument needed, given this is available in instance memeber this.incrementCapacityBy? - consider renaming request() => ensureCapacity() - consider folding adjustCapacity(), instantiateItems() into this method, as below: private void ensureCapacity(int capacity) { if (capacity > this.buffer.size()) { int currCapacity = this.buffer.size(); int newCapacity = currCapacity + incrementCapacityBy; while (newCapacity < capacity) { newCapacity += incrementCapacityBy; } this.buffer.ensureCapacity(newCapacity); // initialize new entries for (int i = currCapacity; i < newCapacity; i++) { this.buffer.add(itemClass.newInstance()); } } } intg/src/main/java/org/apache/atlas/utils/FixedBufferList.java Lines 71 (patched) <https://reviews.apache.org/r/72666/#comment310225> adjustCapacity() => ensureCapacity() intg/src/main/java/org/apache/atlas/utils/FixedBufferList.java Lines 87 (patched) <https://reviews.apache.org/r/72666/#comment310227> Consider moving instantiateItems() into adjustCapacity() implementation; this will avoid callers of adjustCapacity() to call instantiateItems() as well . intg/src/main/java/org/apache/atlas/utils/FixedBufferListAccessor.java Lines 44 (patched) <https://reviews.apache.org/r/72666/#comment310228> Why does this block need to be under synchronized? No state is updated in this block. intg/src/test/java/org/apache/atlas/utils/FixedBufferListAccessorTest.java Lines 33 (patched) <https://reviews.apache.org/r/72666/#comment310229> verifyPeriodicPurge() - the method name doesn't seem to related the implementation. Please review and update. repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditListenerV2.java Lines 90 (patched) <https://reviews.apache.org/r/72666/#comment310230> FixedBufferListAccessor class doesn't seem to add much value. Consider the following simper usage: private static final ThreadLocal<FixedBufferList<EntityAuditEventV2>> AUDIT_EVENTS_BUFFER = new ThreadLocal.withInitial(() -> new FixedBufferList<EntityAuditEventV2>(FIXED_BUFFER_INITIAL_SIZE_DEFAULT, FIXED_BUFFER_INCREMENT_DEFAULT)); Note the use of 'static' above; fixedBufferListAccessor can also be eliminated. You might consider a simple accesser method in EntityAuditListenerV2: private FixedBufferList<EntityAuditEventV2> getAuditEventsBuffer() { return AUDIT_EVENTS_BUFFER.get(); } Same applies for EntityNotificationListenerV2 as well. - Madhan Neethiraj On July 23, 2020, 6:48 p.m., Ashutosh Mestry wrote: > > ----------------------------------------------------------- > This is an automatically generated e-mail. To reply, visit: > https://reviews.apache.org/r/72666/ > ----------------------------------------------------------- > > (Updated July 23, 2020, 6:48 p.m.) > > > Review request for atlas, Madhan Neethiraj, Nikhil Bonte, Nixon Rodrigues, > and Sarath Subramanian. > > > Bugs: ATLAS-3878 > https://issues.apache.org/jira/browse/ATLAS-3878 > > > Repository: atlas > > > Description > ------- > > **Background** > See JIRA for details. > > *Analysis* Using memory profiling tools, it was observed that large number of > notification objects were created. These stayed in memory and later were > promoted to higher generation, thereby taking even longer to be collected. > > **Approach** > Using the fixed-buffer approach to address the problem of creating large > number of small objects. > > New *FixedBufferList* This is an encapsulation over *ArrayList*. During > initial allocation, list is populated with default values. Features: > - Setting of values to these pre-allocated objects is achieved by first doing > a *get* on the element and then assigning values to it. > - *toList* fetches the sub-list from the encapsulating list. This uses the > state within the class to fetch the right length for the returning array. > > New *NamedFixedBufferList* Maintains a per-thread *FixedBufferList*. This is > necessary since the list is now part class's state. > Modified *EntityAuditListenerV2* Uses the new classes. > Modifed *EntityNotificationListener* Uses the new classes. > > **Verification** > - Using the test setup, the memory usage was observed over a period of 24 > hrs. > - Memory usage and object allocation was obvserved using memory profiler. > > > Diffs > ----- > > intg/src/main/java/org/apache/atlas/AtlasConfiguration.java 2c007ca01 > intg/src/main/java/org/apache/atlas/utils/FixedBufferList.java PRE-CREATION > intg/src/main/java/org/apache/atlas/utils/FixedBufferListAccessor.java > PRE-CREATION > intg/src/test/java/org/apache/atlas/utils/FixedBufferListAccessorTest.java > PRE-CREATION > intg/src/test/java/org/apache/atlas/utils/FixedBufferListTest.java > PRE-CREATION > > repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditListenerV2.java > 79527acfa > > webapp/src/main/java/org/apache/atlas/notification/EntityNotificationListenerV2.java > a677b315c > > > Diff: https://reviews.apache.org/r/72666/diff/7/ > > > Testing > ------- > > **Unit testing** > Unit tests added for the new classes. > > **Volume testing** > Setup: > - Node: Threads 40, Core: 40, Allocated Memory: 12 GB > - Multiple Kafka queues ingesting data. > - Bulk entity creation using custom script ingesting 100M entities. > > Memory usage stayed between 0 and 5% during the 24 hr period. > > With: > - Workers: 64 > - Batch size: 50 (fewer elements in batch improve commit time and audit write > time). > - Throughput: ~1.2 M entities per hour. Without out of memory error. > > **Pre-commit** > https://builds.apache.org/view/A/view/Atlas/job/PreCommit-ATLAS-Build-Test/2035/ > > > Thanks, > > Ashutosh Mestry > >