You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by Marty Weiner <ma...@pinterest.com> on 2011/09/17 09:02:45 UTC
Java Thrift is allocation heavy
I'm trying to understand (what I think is) a bug in the generated java
code. My thrift schema generates this method:
public List<Long> listGet(String key) throws org.apache.thrift.TException {
... }
To avoid an allocation on every listGet request, I'd like to keep a
pre-allocated List<Long> buffer per thread, fill that, and return it. When
I do this, it doesn't take much for me to get a ConcurrentModificationError,
possibly because the wrappers around my listGet method are holding onto it?
What's the recommended way to avoid the extra allocations?
Re: Java Thrift is allocation heavy
Posted by Marty Weiner <ma...@pinterest.com>.
Ah excellent. So for avoiding allocation on a get request, you're suggesting I make a threadlocal buffer? Or should it be a pool that reclaims objects instead of garbage collect them (not sure if that is possible).
On Sep 20, 2011, at 5:08 PM, Bryan Duxbury <br...@rapleaf.com> wrote:
> No, Thrift does not supply any threadsafe area. You have to use an object
> pool or ThreadLocal variable, etc.
>
> On Tue, Sep 20, 2011 at 4:27 PM, Marty Weiner <ma...@pinterest.com> wrote:
>
>> Ah ok. It is multithreaded and concurrent requests are allowed. Is there
>> a threadsafe area to allocate from? I assumed each handler object was its
>> own thread.
>>
>> On Sep 20, 2011, at 11:38 AM, Bryan Duxbury <br...@rapleaf.com> wrote:
>>
>>> Are you using a multithreaded TServer with concurrent client requests? If
>>> so, then you can't declare just a single list in your handler. Handler
>>> access is not threadsafe.
>>>
>>> On Tue, Sep 20, 2011 at 11:01 AM, Marty Weiner <ma...@pinterest.com>
>> wrote:
>>>
>>>> Ah, sorry, I should have been clearer. This is from the server end.
>>>>
>>>> Some other thread can easily serialize my data? So then that means that
>> I
>>>> must always
>>>> allocate a new List<Long> and return it? Is there a way to avoid the
>>>> allocation overhead? I'd
>>>> prefer to have my GC activity not scale with frequency of read requests,
>> if
>>>> possible.
>>>>
>>>> By "thread local", I was referring to lists I allocated in my
>> handler.java
>>>> file (the derivation
>>>> of the interfaces made by the thrift generator).
>>>>
>>>> Thanks for the help!
>>>>
>>>> On Tue, Sep 20, 2011 at 9:21 AM, Bryan Duxbury <br...@rapleaf.com>
>> wrote:
>>>>
>>>>> I presume that you're talking about this method from the server side of
>>>>> things. The problem is that, depending on the TServer you're using,
>> when
>>>>> you
>>>>> return the List<Long>, it might not necessarily be getting serialized
>> in
>>>>> the
>>>>> same thread.
>>>>>
>>>>> Also, what is your "per thread" reservation mechanism? ThreadLocals?
>>>>>
>>>>> On Sat, Sep 17, 2011 at 12:02 AM, Marty Weiner <ma...@pinterest.com>
>>>>> wrote:
>>>>>
>>>>>> I'm trying to understand (what I think is) a bug in the generated java
>>>>>> code. My thrift schema generates this method:
>>>>>> public List<Long> listGet(String key) throws
>>>> org.apache.thrift.TException
>>>>> {
>>>>>> ... }
>>>>>>
>>>>>> To avoid an allocation on every listGet request, I'd like to keep a
>>>>>> pre-allocated List<Long> buffer per thread, fill that, and return it.
>>>>> When
>>>>>> I do this, it doesn't take much for me to get a
>>>>>> ConcurrentModificationError,
>>>>>> possibly because the wrappers around my listGet method are holding
>> onto
>>>>> it?
>>>>>> What's the recommended way to avoid the extra allocations?
>>>>>>
>>>>>
>>>>
>>
Re: Java Thrift is allocation heavy
Posted by Bryan Duxbury <br...@rapleaf.com>.
No, Thrift does not supply any threadsafe area. You have to use an object
pool or ThreadLocal variable, etc.
On Tue, Sep 20, 2011 at 4:27 PM, Marty Weiner <ma...@pinterest.com> wrote:
> Ah ok. It is multithreaded and concurrent requests are allowed. Is there
> a threadsafe area to allocate from? I assumed each handler object was its
> own thread.
>
> On Sep 20, 2011, at 11:38 AM, Bryan Duxbury <br...@rapleaf.com> wrote:
>
> > Are you using a multithreaded TServer with concurrent client requests? If
> > so, then you can't declare just a single list in your handler. Handler
> > access is not threadsafe.
> >
> > On Tue, Sep 20, 2011 at 11:01 AM, Marty Weiner <ma...@pinterest.com>
> wrote:
> >
> >> Ah, sorry, I should have been clearer. This is from the server end.
> >>
> >> Some other thread can easily serialize my data? So then that means that
> I
> >> must always
> >> allocate a new List<Long> and return it? Is there a way to avoid the
> >> allocation overhead? I'd
> >> prefer to have my GC activity not scale with frequency of read requests,
> if
> >> possible.
> >>
> >> By "thread local", I was referring to lists I allocated in my
> handler.java
> >> file (the derivation
> >> of the interfaces made by the thrift generator).
> >>
> >> Thanks for the help!
> >>
> >> On Tue, Sep 20, 2011 at 9:21 AM, Bryan Duxbury <br...@rapleaf.com>
> wrote:
> >>
> >>> I presume that you're talking about this method from the server side of
> >>> things. The problem is that, depending on the TServer you're using,
> when
> >>> you
> >>> return the List<Long>, it might not necessarily be getting serialized
> in
> >>> the
> >>> same thread.
> >>>
> >>> Also, what is your "per thread" reservation mechanism? ThreadLocals?
> >>>
> >>> On Sat, Sep 17, 2011 at 12:02 AM, Marty Weiner <ma...@pinterest.com>
> >>> wrote:
> >>>
> >>>> I'm trying to understand (what I think is) a bug in the generated java
> >>>> code. My thrift schema generates this method:
> >>>> public List<Long> listGet(String key) throws
> >> org.apache.thrift.TException
> >>> {
> >>>> ... }
> >>>>
> >>>> To avoid an allocation on every listGet request, I'd like to keep a
> >>>> pre-allocated List<Long> buffer per thread, fill that, and return it.
> >>> When
> >>>> I do this, it doesn't take much for me to get a
> >>>> ConcurrentModificationError,
> >>>> possibly because the wrappers around my listGet method are holding
> onto
> >>> it?
> >>>> What's the recommended way to avoid the extra allocations?
> >>>>
> >>>
> >>
>
Re: Java Thrift is allocation heavy
Posted by Marty Weiner <ma...@pinterest.com>.
Ah ok. It is multithreaded and concurrent requests are allowed. Is there a threadsafe area to allocate from? I assumed each handler object was its own thread.
On Sep 20, 2011, at 11:38 AM, Bryan Duxbury <br...@rapleaf.com> wrote:
> Are you using a multithreaded TServer with concurrent client requests? If
> so, then you can't declare just a single list in your handler. Handler
> access is not threadsafe.
>
> On Tue, Sep 20, 2011 at 11:01 AM, Marty Weiner <ma...@pinterest.com> wrote:
>
>> Ah, sorry, I should have been clearer. This is from the server end.
>>
>> Some other thread can easily serialize my data? So then that means that I
>> must always
>> allocate a new List<Long> and return it? Is there a way to avoid the
>> allocation overhead? I'd
>> prefer to have my GC activity not scale with frequency of read requests, if
>> possible.
>>
>> By "thread local", I was referring to lists I allocated in my handler.java
>> file (the derivation
>> of the interfaces made by the thrift generator).
>>
>> Thanks for the help!
>>
>> On Tue, Sep 20, 2011 at 9:21 AM, Bryan Duxbury <br...@rapleaf.com> wrote:
>>
>>> I presume that you're talking about this method from the server side of
>>> things. The problem is that, depending on the TServer you're using, when
>>> you
>>> return the List<Long>, it might not necessarily be getting serialized in
>>> the
>>> same thread.
>>>
>>> Also, what is your "per thread" reservation mechanism? ThreadLocals?
>>>
>>> On Sat, Sep 17, 2011 at 12:02 AM, Marty Weiner <ma...@pinterest.com>
>>> wrote:
>>>
>>>> I'm trying to understand (what I think is) a bug in the generated java
>>>> code. My thrift schema generates this method:
>>>> public List<Long> listGet(String key) throws
>> org.apache.thrift.TException
>>> {
>>>> ... }
>>>>
>>>> To avoid an allocation on every listGet request, I'd like to keep a
>>>> pre-allocated List<Long> buffer per thread, fill that, and return it.
>>> When
>>>> I do this, it doesn't take much for me to get a
>>>> ConcurrentModificationError,
>>>> possibly because the wrappers around my listGet method are holding onto
>>> it?
>>>> What's the recommended way to avoid the extra allocations?
>>>>
>>>
>>
Re: Java Thrift is allocation heavy
Posted by Bryan Duxbury <br...@rapleaf.com>.
Are you using a multithreaded TServer with concurrent client requests? If
so, then you can't declare just a single list in your handler. Handler
access is not threadsafe.
On Tue, Sep 20, 2011 at 11:01 AM, Marty Weiner <ma...@pinterest.com> wrote:
> Ah, sorry, I should have been clearer. This is from the server end.
>
> Some other thread can easily serialize my data? So then that means that I
> must always
> allocate a new List<Long> and return it? Is there a way to avoid the
> allocation overhead? I'd
> prefer to have my GC activity not scale with frequency of read requests, if
> possible.
>
> By "thread local", I was referring to lists I allocated in my handler.java
> file (the derivation
> of the interfaces made by the thrift generator).
>
> Thanks for the help!
>
> On Tue, Sep 20, 2011 at 9:21 AM, Bryan Duxbury <br...@rapleaf.com> wrote:
>
> > I presume that you're talking about this method from the server side of
> > things. The problem is that, depending on the TServer you're using, when
> > you
> > return the List<Long>, it might not necessarily be getting serialized in
> > the
> > same thread.
> >
> > Also, what is your "per thread" reservation mechanism? ThreadLocals?
> >
> > On Sat, Sep 17, 2011 at 12:02 AM, Marty Weiner <ma...@pinterest.com>
> > wrote:
> >
> > > I'm trying to understand (what I think is) a bug in the generated java
> > > code. My thrift schema generates this method:
> > > public List<Long> listGet(String key) throws
> org.apache.thrift.TException
> > {
> > > ... }
> > >
> > > To avoid an allocation on every listGet request, I'd like to keep a
> > > pre-allocated List<Long> buffer per thread, fill that, and return it.
> > When
> > > I do this, it doesn't take much for me to get a
> > > ConcurrentModificationError,
> > > possibly because the wrappers around my listGet method are holding onto
> > it?
> > > What's the recommended way to avoid the extra allocations?
> > >
> >
>
Re: Java Thrift is allocation heavy
Posted by Marty Weiner <ma...@pinterest.com>.
Ah, sorry, I should have been clearer. This is from the server end.
Some other thread can easily serialize my data? So then that means that I
must always
allocate a new List<Long> and return it? Is there a way to avoid the
allocation overhead? I'd
prefer to have my GC activity not scale with frequency of read requests, if
possible.
By "thread local", I was referring to lists I allocated in my handler.java
file (the derivation
of the interfaces made by the thrift generator).
Thanks for the help!
On Tue, Sep 20, 2011 at 9:21 AM, Bryan Duxbury <br...@rapleaf.com> wrote:
> I presume that you're talking about this method from the server side of
> things. The problem is that, depending on the TServer you're using, when
> you
> return the List<Long>, it might not necessarily be getting serialized in
> the
> same thread.
>
> Also, what is your "per thread" reservation mechanism? ThreadLocals?
>
> On Sat, Sep 17, 2011 at 12:02 AM, Marty Weiner <ma...@pinterest.com>
> wrote:
>
> > I'm trying to understand (what I think is) a bug in the generated java
> > code. My thrift schema generates this method:
> > public List<Long> listGet(String key) throws org.apache.thrift.TException
> {
> > ... }
> >
> > To avoid an allocation on every listGet request, I'd like to keep a
> > pre-allocated List<Long> buffer per thread, fill that, and return it.
> When
> > I do this, it doesn't take much for me to get a
> > ConcurrentModificationError,
> > possibly because the wrappers around my listGet method are holding onto
> it?
> > What's the recommended way to avoid the extra allocations?
> >
>
Re: Java Thrift is allocation heavy
Posted by Bryan Duxbury <br...@rapleaf.com>.
I presume that you're talking about this method from the server side of
things. The problem is that, depending on the TServer you're using, when you
return the List<Long>, it might not necessarily be getting serialized in the
same thread.
Also, what is your "per thread" reservation mechanism? ThreadLocals?
On Sat, Sep 17, 2011 at 12:02 AM, Marty Weiner <ma...@pinterest.com> wrote:
> I'm trying to understand (what I think is) a bug in the generated java
> code. My thrift schema generates this method:
> public List<Long> listGet(String key) throws org.apache.thrift.TException {
> ... }
>
> To avoid an allocation on every listGet request, I'd like to keep a
> pre-allocated List<Long> buffer per thread, fill that, and return it. When
> I do this, it doesn't take much for me to get a
> ConcurrentModificationError,
> possibly because the wrappers around my listGet method are holding onto it?
> What's the recommended way to avoid the extra allocations?
>