Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FluentLogFactory: Why use WeakHashMap to store loggers? #37

Closed
todesking opened this issue Nov 19, 2014 · 10 comments
Closed

FluentLogFactory: Why use WeakHashMap to store loggers? #37

todesking opened this issue Nov 19, 2014 · 10 comments
Assignees

Comments

@todesking
Copy link
Contributor

        FluentLoggerFactory factory = new FluentLoggerFactory();
        ArrayList<FluentLogger> loggers = new ArrayList<FluentLogger>();
        for(int i=0; i<100; i++) {
            loggers.add(factory.getLogger("testtag" + i, "localhost", 999));
        }
        System.gc();
        assertEquals(loggers.size(), factory.getLoggers().size());

The last assertion is sometimes failed. That because WeakHashMap has weak-referenced keys and strong-referenced values, so when key(String generated in FluentLoggerFactory#getLogger()) is GCed, correspond logger is removed from the map.

Because of this, FluentLogerFactory#closeAll() and flushAll() has unexpected behaviour: Some loggers are closed/flushed, and rest is not touched.

It seems just a bug and use normal HashMap to fix it. Is this correct?

@komamitsu
Copy link
Member

@todesking Thanks for your report.

@muga Why did you change the implementation of Map from HashMap to WeakHashMap at d5efd4d?

@komamitsu
Copy link
Member

@muga Any updates?

@muga
Copy link
Member

muga commented Dec 5, 2014

@todesking We've used WeakHashMap and finalize method for reducing the heap space consumption. I thought and considered the possibility that some users create a lot of FluentLogger objects on his JVM. But the implementation is not good in some cases, you know.

@komamitsu We should remove FluentLoggerFactory (and the WeakHashMap impl.) from external API. FluentLogger objects and the object creations should be managed by users.

@oza
Copy link
Member

oza commented Dec 5, 2014

@todesking good catch, thanks for your report.
We have 2 options:

  1. Reverting the store of FluentLoggerFactory to HashMap.
  2. Removing FluentLoggerFactory.

I prefer to use 1. for the backward compatibility. Also, users can choose whether they manage the object by themselves or by FluentLoggerFactory. For handling small number of the objects, it's enough.

@komamitsu
Copy link
Member

@muga @oza Thanks for your ideas.

For option 1, I'm concerned about memory consumption because all FluentLoggers stored in HashMap are never released. I think option 2 is simple and isn't confusable. Of course, backward compatibility is important, though as you said.

Also, users can choose whether they manage the object by themselves or by FluentLoggerFactory.

FluentLogger internally depends on FluentLogFactory. https://github.com/fluent/fluent-logger-java/blob/master/src/main/java/org/fluentd/logger/FluentLogger.java#L32. So we need to remove the dependency from FluentLogger if we choose this option.

@oza
Copy link
Member

oza commented Dec 5, 2014

@komamitsu Rethinking of this - how about having the key of WeakHashMap at FluentLogger via FluentLogger#setFactoryKey or something to prevent the GC? When a instance of FluentLogger#close()
is called, resource management can be done by setting key as null.

@komamitsu
Copy link
Member

@oza Make sense.
But adding another attribute into FluentLogger may make it more complicated. Also, factoryKey doesn't sound an essential information for FluentLogger...

I think the cause of this problem is the way of holding a reference of FluentLogger in FluentLoggerFactory. I created a PR (#38) for it. The PR has the following little downsides. But I think they are ignorable.

  • FluentLoggerFactory#getLogger linearly searches for a FluentLogger which has the same key consists of tagPrefix, host, port and so on. But the number of FluentLogger entries won't be large actually.
  • FluentLoggerFactory#getLoggers broke the compatibility. But this method is package private and only for test.

What do you think?

@oza
Copy link
Member

oza commented Dec 6, 2014

@komamitsu I agree with your idea. @muga what do you think?

@muga
Copy link
Member

muga commented Dec 7, 2014

@komamitsu @oza thank you for driving this issue and fixing. #38 looks good to me to fix this issue. compatibility is important:-)

@oza
Copy link
Member

oza commented Dec 7, 2014

@muga @komamitsu Merged #38.

@todesking Thanks for your reporting!

@oza oza closed this as completed Dec 7, 2014
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

No branches or pull requests

4 participants