Skip to content

Conversation

@vancobuca
Copy link

On allocation failures, before throwing an out of memory exception, the base allocator makes a listener callback, giving the user code a change to correct its memory usage -- perhaps flush some state; perhaps clear out some caches; or perhaps trade-off some limits.

The AllocationListener has a new method added:
boolean onFailedAllocation(long size, Accountant.AllocationOutcome outcome)
with the semantics: return 'true' if the allocation can be retried (presumably after the code altered the state in some way), or 'false' if not.

If the listener asks for a retry, the allocator retries exactly once.

@siddharthteotia
Copy link
Contributor

@codecov-io
Copy link

codecov-io commented Jun 11, 2018

Codecov Report

Merging #2133 into master will increase coverage by 0.02%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2133      +/-   ##
==========================================
+ Coverage   86.39%   86.41%   +0.02%     
==========================================
  Files         242      242              
  Lines       41475    41496      +21     
==========================================
+ Hits        35832    35859      +27     
+ Misses       5643     5637       -6
Impacted Files Coverage Δ
python/pyarrow/tests/test_table.py 100% <0%> (ø) ⬆️
python/pyarrow/tests/test_parquet.py 95.54% <0%> (+0.01%) ⬆️
python/pyarrow/tests/test_convert_pandas.py 94.85% <0%> (+0.01%) ⬆️
python/pyarrow/pandas_compat.py 97.85% <0%> (+0.02%) ⬆️
python/pyarrow/table.pxi 69% <0%> (+0.33%) ⬆️
cpp/src/arrow/compute/kernels/cast.cc 89.87% <0%> (+0.51%) ⬆️
python/pyarrow/public-api.pxi 52.17% <0%> (+2.89%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 34890cc...4f64f96. Read the comment docs.

Copy link
Contributor

@jacques-n jacques-n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good. Few minor comments.

final ChildAllocator childAllocator = new ChildAllocator(this, name, initReservation,
maxAllocation);
final ChildAllocator childAllocator = new ChildAllocator(listener,this, name, initReservation,
maxAllocation);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird indenting here and elsewhere.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Please note that this passed the check style

// Allocation listener
// It counts the number of times it has been invoked, and how much memory allocation it has seen
// When set to 'expand on fail', it attempts to expand the associated allocator's limit
static class TestAllocationListener implements AllocationListener {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private final?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

int getNumCalls() {
return numCalls;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be able to do this count number of calls monitoring using Jmockit's APIs rather than custom building something.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, and in fact I had it like that initially. However, I found I was repeating code again and again in the mocks, and it was much easier to just build a custom listener.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack

// Second try, in case the listener can do something about it
outcome = this.allocateBytes(actualRequestSize);
}
if (!outcome.isOk()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's avoid checking twice in the base case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

private BaseAllocator(
protected BaseAllocator(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we update the protected constructor/consolidate? Would rather not expose more constructors.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to update/consolidate, short of removing the previous two protected constructors -- which breaks the public interface, and thus probably not the best idea. I cannot use the existing constructors since I need to support listener instances that are not common to the entire hierarchy.
Suggestions are welcome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is okay changing the constructor signature of BaseAllocator and consolidate overlap

@xhochy xhochy changed the title Arrow 2696: [JAVA] enhance AllocationListener with an onFailedAllocation() call ARROW-2696: [JAVA] enhance AllocationListener with an onFailedAllocation() call Jun 12, 2018
Copy link
Member

@BryanCutler BryanCutler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @vancobuca! Generally I feel it's better to catch the OOM exception where it's appropriate because then you have the context of what is being attempted, and take that into account for any retries. But I guess this can be helpful too in some cases, so looks ok to me.

assertOpen();

final ChildAllocator childAllocator = new ChildAllocator(this, name, initReservation,
final ChildAllocator childAllocator = new ChildAllocator(listener,this, name, initReservation,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing a space between listener,this

Copy link
Contributor

@siddharthteotia siddharthteotia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, will merge by evening if no more comments

@siddharthteotia siddharthteotia merged commit 392fd02 into apache:master Jun 15, 2018
pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ion() call (apache#2133)

* Explicit listener added to newChildAllocator(), allowing each child to have a separate listener instance

* AllocationListener.onFailedAlloc() method added, with default no-op implementation

* Call to onFailedAlloc() implemented

* Review comments

* Review comment: missing space

* Consolidated BaseAllocator constructors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants