Thanks Marshall for the detailed analysis.

My comment about you commenting was actually pointing to the memory
consumption of the c++ near uima implementation. I guess Dennis was
referring to that but I am not sure. My opinion is that the memory is
consumed exactly by what you described, and especially by the conetent
of the three fields.


The approach storing additional information about the location and
coverage of annotations in an annotation was always questioned by me (at
least a bit). There are several other options to implement it, e.g.,
maybe using a custom index. I decided to use annotations for different
reasons and I do not know if it is the best solution.


The memory consumption can be reduced by optimizing the data structures,
but I think reducing the amount of information that is stored or needs
to be stored is a more fruitful way to go. I implemented an experimental
prototype but the effect was not yet as big as I hoped for. One reason
is that still too much is stored in RutaBasic which is required by some
functionality, e.g., partof is required by sequential matching because
of the coverage-based visibility concept, not only required by the
PARTOF condition. The visibility concept is not optional even if it is
not required in the actual script.


For optimizing ruta, we need some fixed evaluation setting for different
but common use case so that we do not only improve the implementation
for large documents or specific kind of rules. For adapting to different
use case of ruta, the encapsulation in ruta needs to be increased, e.g.,
RutaStream needs to be refactored and needs to be replaceable with other
implementation. The good thing is that ruta-core has enough unit tests
compared to a few years ago so that such drastic changes can be
implemented now.


There can be no quick solution right now. I'll try to find some
compromise for the next rc and try to get ruta released as soon as
possible since there are so many bugfixes waiting.


Peter



Am 28.02.2017 um 21:42 schrieb Marshall Schor:
> Re: space taken by ArrayLists for the 3 fields "partof", "beginMap", 
> "endMap". 
> Let's assume the number of distinct UIMA types in your application is 100.  
> (Is
> this approximately right, or way off?).
>
> Each Ruta instance would include 3 ArrayLists, each of which would be an array
> of 100 Java References.  If you're running with < 32 GB heap, modern Javas 
> store
> references as 4 byte things.  So the approximate space taken by these 
> arraylists
> would be Object-Overhead + some-fields-in-ArrayList +
> ObjectOverhead-for-ref-array + the-array-size.
>
> The last element is what you could potentially reduce with smaller array
> allocation.  It's size is 4 * 100 (with above assumption) = 400 bytes.
>
> The overhead per java object runs maybe 24-32 bytes, so 2 of these would be, 
> say
> 50 bytes.  And then there's some more for ArrayList items, perhaps.  These are
> "fixed".
>
> So, you might end up with 500 bytes per field, or 1500 for the 3 fields at the
> beginning.
>
> (This would be the size assuming these have no contents in them, of course).
>
> A lower bound for 250K instances of RutaBasic (just considering these 3 
> fields)
> would then be 250,000 * 500 = 125,000,000.  This is in the ballpark of your
> estimate.
>
> One possible design revision to ease this may be to consider if all 250K
> instances of RutaBasic need to be in memory at a time.
>
> -Marshall
>
> On 2/28/2017 7:54 AM, Peter Klügl (JIRA) wrote:
>>     [ 
>> https://issues.apache.org/jira/browse/UIMA-5306?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15887936#comment-15887936
>>  ] 
>>
>> Peter Klügl commented on UIMA-5306:
>> -----------------------------------
>>
>> Maybe Marshall can comment on the memory consumption of the addresses? I 
>> assume that the bottleneck is rather ruta. Have you measured the memory 
>> footprint of your use case with about the same amount of annotations without 
>> ruta?
>>
>> I know drools and rete a bit, but not PHREAK. I have to take a look. I 
>> thought about automatic optimizations before but only for the speed. The 
>> increased expressiveness of ruta makes this really complicated. As a 
>> consequence, generic, all-encompassing automatic optimizations are not 
>> really possible without restricting the expressiveness. Thus, only small 
>> optimizations have been added in patches. There are also differences between 
>> production rule systems and regular expression rule systems/FST.
>> I have not thought about automatic optimization concerning the memory 
>> consumption. Maybe the situation will get better with uima 3 where the GC 
>> can clean up stuff. There are still many possibilities to improve ruta 
>> concerning speed and memory consumption, e.g., the prototype of the type 
>> usage I implemented the last days. Or think about running ruta without 
>> RutaBasic at all.
>> After all, it is always about the time one can invest to improve the system. 
>> The further development, fixes and new features have always been driven by 
>> current requirements, e.g., when it was not fast enough I did something to 
>> improve the speed. 
>> Your idea of removing information, that is not needed anymore, is very nice 
>> and would be implementable if the type usage information is stored for every 
>> other step in the rules, (and with some sort of dynamic RutaBasic). However, 
>> I would bet that there are lower fruits.
>>
>> You are very welcome to participate. Ruta was born about 10 years ago and 
>> not every part was developed in the same speed or with the same care. There 
>> are still a lot of inherited waste and legacy issues, but I try to 
>> constantly improve at least the code quality of ruta-core, which is also the 
>> part that matters the most.  If I can help you to get into the project 
>> somehow, just let me know. Even if you just point out code that should be 
>> refactored.
>> Yeah, the RutaParser is terrible long, but most is just syntax grammar for 
>> conditions and actions. I did not replace that for a generic rule so that I 
>> do not lose the argument checks. 
>>
>>
>>> Memory Improvement - Unnecessary leaks
>>> --------------------------------------
>>>
>>>                 Key: UIMA-5306
>>>                 URL: https://issues.apache.org/jira/browse/UIMA-5306
>>>             Project: UIMA
>>>          Issue Type: Improvement
>>>          Components: Ruta
>>>    Affects Versions: 2.3.0ruta
>>>         Environment: Windows 10, JVM with -Xmx 1024, Java JDK 1.8., 16gb 
>>> memory
>>>            Reporter: Dennis Bauer
>>>            Assignee: Peter Klügl
>>>
>>> In a productive setup we figured out, that there is a huge memory usage of 
>>> Ruta itself. With JVisualVM it's easy to see, that there is a relative 
>>> small amount of arrays of Arraylists but with a high memory consumption 
>>> (250k instances result in 243 000 000 byte memory that are reserved)
>>> The problem is, that in a clustered SaaS environment with less memory, 
>>> these arrays block relevant space in memory. A deeper look into these 
>>> Arrays of Arraylist let suggest the class 
>>> org.apache.uima.ruta.type.RutaBasic
>>> A look at this class show three arrays that are instanced with the max. 
>>> possible value, that can be returned by the typesystem of CAS. 
>>> {code:Java}
>>>   private int[] partOf = new int[((TypeSystemImpl) 
>>> getCAS().getTypeSystem()).getLargestTypeCode()];
>>>   private Collection<?>[] beginMap = new ArrayList<?>[((TypeSystemImpl) 
>>> getCAS().getTypeSystem())
>>>           .getLargestTypeCode()];
>>>   private Collection<?>[] endMap = new ArrayList<?>[((TypeSystemImpl) 
>>> getCAS().getTypeSystem())
>>>           .getLargestTypeCode()];
>>>               
>>> {code}
>>> In this improvement should be done an dynamic allocation of memory usage 
>>> for these arrays, so the total memory consumption would be reduced.
>>
>> --
>> This message was sent by Atlassian JIRA
>> (v6.3.15#6346)
>>

Reply via email to