> How did you kill the TaskManagers? I assume you didn't kill the JVM
process because otherwise you wouldn't see the finalizer objects piling up.

Till, I configure Chao Monkey to always kill the newest/same TaskManager.
So other N-1 TaskManagers stayed up during the whole process. Each of them
experience a job restart for each kill. Then I saw the deferred memory
cleanup by finalizer.

On Tue, Sep 19, 2017 at 9:58 AM, Steven Wu <stevenz...@gmail.com> wrote:

> Stephan, agree that it is not a real memory leak. I haven't found it
> affecting the system. so it is sth odd for now.
>
> but if it is not really necessary, why do we want to defer memory release
> with unpredictable behavior? can StreamTask stop() method take care of the
> cleanup work and don't need to rely on finalizer() or PhantomReference?
>
> On Tue, Sep 19, 2017 at 2:56 AM, Stephan Ewen <se...@apache.org> wrote:
>
>> Hi!
>>
>> From my understanding, overriding finalize() still has some use cases and
>> is valid if done correctly, (although PhantomReference has more control
>> over the cleanup process). finalize() is still used in JDK classes as well.
>>
>> Whenever one overrides finalize(), the object cannot be immediately
>> garbage collected because the finalize() method may make it reachable
>> again. It results in the following life cycle:
>>
>>   1) object becomes unreachable, is detected eligible for GC
>>   2) In the GC cycle, object is NOT collected, but finalize() is called
>>   3) If object is still not reachable, it will be collected in the
>> subsequent GC cycle
>>
>> In essence, objects that override finalize() stay for one more GC cycle.
>> That may be what you are seeing. It should not be a real memory leak, but
>> deferred memory release.
>>
>> Is this a problem that is affecting the system, or only something that
>> seems odd for now?
>>
>> If you are very concerned about this, would you be up to contribute a
>> change that uses a PhantomReference and Reference Queue for cleanup instead?
>>
>> Stephan
>>
>>
>> On Tue, Sep 19, 2017 at 12:56 AM, Till Rohrmann <trohrm...@apache.org>
>> wrote:
>>
>>> Hi Steven,
>>>
>>> the finalize method in StreamTask acts as a safety net in case the
>>> services of the StreamTask haven't been properly shut down. In the code,
>>> however, it looks as if the TimerService, for example, is always being
>>> stopped in the finally block of the invoke method. Thus, it might not be
>>> necessary to have the finalize method as a safety net.
>>>
>>> How did you kill the TaskManagers? I assume you didn't kill the JVM
>>> process because otherwise you wouldn't see the finalizer objects piling up.
>>>
>>> I think that you can create a JIRA issue for removing the finalizer
>>> method.
>>>
>>> Cheers,
>>> Till
>>>
>>>
>>>
>>> On Thu, Sep 14, 2017 at 12:26 PM, Fabian Hueske <fhue...@gmail.com>
>>> wrote:
>>>
>>>> Hi Steven,
>>>>
>>>> thanks for reporting this issue.
>>>> Looping in Till who's more familiar with the task lifecycles.
>>>>
>>>> Thanks, Fabian
>>>>
>>>> 2017-09-12 7:08 GMT+02:00 Steven Wu <stevenz...@gmail.com>:
>>>>
>>>>> Hi ,
>>>>>
>>>>> I was using Chaos Monkey to test Flink's behavior against frequent
>>>>> killing of task manager nodes. I found that stopped/disposed StreamTask 
>>>>> got
>>>>> retained by java finalizer. It is kind like a memory leak. Since each
>>>>> StreamTask retains 2.6 MB memory. With 20 kills (and job restarts) for
>>>>> 8-CPU container, there are 2.6 * 20 * 8 MB retained in heap.
>>>>>
>>>>> [image: Inline image 1]
>>>>>
>>>>> finalize() is generally not recommended for cleanup, because "*Finalizers
>>>>> are unpredictable, often dangerous, and generally unnecessary*",
>>>>> quoted from Joshua Bloch's book.
>>>>> http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7
>>>>>
>>>>> This code from StreamTask.java seems to be the cause. Is it necessary?
>>>>> can it be removed? We are using flink-1.2 release branch. But I see the
>>>>> same code in flink-1.3 and master branch
>>>>>
>>>>> /**
>>>>> * The finalize method shuts down the timer. This is a fail-safe
>>>>> shutdown, in case the original
>>>>> * shutdown method was never called.
>>>>> *
>>>>> * <p>
>>>>> * This should not be relied upon! It will cause shutdown to happen
>>>>> much later than if manual
>>>>> * shutdown is attempted, and cause threads to linger for longer than
>>>>> needed.
>>>>> */
>>>>> @Override
>>>>> protected void finalize() throws Throwable {
>>>>> super.finalize();
>>>>> if (timerService != null) {
>>>>> if (!timerService.isTerminated()) {
>>>>> LOG.info("Timer service is shutting down.");
>>>>> timerService.shutdownService();
>>>>> }
>>>>> }
>>>>>
>>>>> cancelables.close();
>>>>> }
>>>>>
>>>>> Thanks,
>>>>> Steven
>>>>>
>>>>
>>>>
>>>
>>
>

Reply via email to