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

每个sql语句都会长期持有引用,加快FullGC频率 #1664

Open
rocky-peng opened this issue Mar 31, 2017 · 9 comments
Open

每个sql语句都会长期持有引用,加快FullGC频率 #1664

rocky-peng opened this issue Mar 31, 2017 · 9 comments

Comments

@rocky-peng
Copy link

@rocky-peng rocky-peng commented Mar 31, 2017

发现fullgc频繁,执行dump操作,发现近45%的内存占用都是存储的sql语句(堆的设置是2G)。跟踪引用关系,找到了JdbcSqlStat类,接着找到JdbcDataSourceStat类,发现如下代码发现是在这持有了sql语句的引用:

public JdbcSqlStat createSqlStat(String sql) {
        lock.writeLock().lock();
        try {
            JdbcSqlStat sqlStat = sqlStatMap.get(sql);
            if (sqlStat == null) {
                sqlStat = new JdbcSqlStat(sql);
                sqlStat.setDbType(this.dbType);
                sqlStat.setName(this.name);
                sqlStatMap.put(sql, sqlStat);  //sqlStatMap是一个LinkedHashMap
            }

            return sqlStat;
        } finally {
            lock.writeLock().unlock();
        }
    }

进一步排查代码,暂时只发现三个方法对sqlStatMap对象存在移除操作:

1. com.alibaba.druid.stat.JdbcDataSourceStat#setMaxSqlSize
2. com.alibaba.druid.stat.JdbcDataSourceStat#reset
3. com.alibaba.druid.stat.JdbcDataSourceStat#getSqlStatMapAndReset

第二个reset方法,发现是通过前端指定的url来触发执行(我们这里的情况是没有调用这个url的)

第三个getSqlStatMapAndReset,发现是在通过注册了一个ServletContextListener来添加了一个定时任务,没隔300second来触发(因为我们这里的应用不是一个web所以也没有触发这个操作)

第一个setMaxSqlSize方法调用关系太多,也就没有一一梳理,不知道这个方法的调用策略是怎样的呢?

@fuyi-wang

This comment has been minimized.

Copy link

@fuyi-wang fuyi-wang commented Nov 7, 2017

楼主这个问题最终是如何解决的啊

@rocky-peng

This comment has been minimized.

Copy link
Author

@rocky-peng rocky-peng commented Nov 8, 2017

@fuyi-wang 我们当初开启了这个功能,但没有使用。找到原因后,就把这个功能给关闭了。线上就正常了。

如果需要使用这个功能的话,可以参考:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

@fuyi-wang

This comment has been minimized.

Copy link

@fuyi-wang fuyi-wang commented Dec 8, 2017

@rocky-peng 我遇到的问题和你的一样,但又想使用 SQL监控的功能,我再查查看有没有其他的解决方案,多谢哈

@pc-fuqq

This comment has been minimized.

Copy link

@pc-fuqq pc-fuqq commented Apr 24, 2019

楼主,我是JdbcDataSourceStat类中属性
ConcurrentMap<Long, JdbcConnectionStat.Entry> connections = new ConcurrentHashMap
内存占用很大,跟你情况差不多,这个map占用内存超过总的一半,最终把StatFilter禁用掉才恢复正常的。

@raydl007

This comment has been minimized.

Copy link

@raydl007 raydl007 commented Jun 15, 2019

一样的情况,springboot项目,运行一天就oom了

@xuexuegege

This comment has been minimized.

Copy link

@xuexuegege xuexuegege commented Feb 27, 2020

@fuyi-wang 现在springboot和druid的自动配置,貌似是默认开启监控的。请问大哥找到解决办法没呢

1 similar comment
@xuexuegege

This comment has been minimized.

Copy link

@xuexuegege xuexuegege commented Feb 27, 2020

@fuyi-wang 现在springboot和druid的自动配置,貌似是默认开启监控的。请问大哥找到解决办法没呢

@rocky-peng

This comment has been minimized.

Copy link
Author

@rocky-peng rocky-peng commented Feb 27, 2020

@xuexuegege 试试自己写工厂方法new出datasurce,new的时候应该有参数设置
image

@xuexuegege

This comment has been minimized.

Copy link

@xuexuegege xuexuegege commented Mar 10, 2020

看了下,springboot集成druid是自动配置的,看了一下源码发现
image
这里默认开启了,所以需要手动设置为false就行了
也就是
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.