[英]Analyzing heap dump from OutOfMemoryError in Java
我的 Java 程序不断出现OutOfMemoryError
,我相信某处存在 memory 泄漏。 在研究这个问题时,多个站点建议使用 Eclipse Memory Analyzer 工具,因此我在命令中添加了-XX:+HeapDumpOnOutOfMemoryError
标志,以在下次发生错误时获取堆转储。 检查转储后,占用最多空间的对象是“com.couchbase.client.core.deps.org.LatencyUtils.LatencyStats 的 17,481 个实例”,由“org.springframework.boot.loader.LaunchedURLClassLoader @ 0x6c7c24510”加载占用 1,978,652,856 (59.03%) 字节。”
我认为这是记录器打印了太多日志,因为 Java Couchbase 代码在INFO
级别打印了很多日志,所以我尝试将日志级别设置为WARN
,但在尝试之后,结果相同。 将不胜感激任何见解或建议,谢谢。
编辑:我们调用 Couchbase 的代码的某些部分:
@Autowired
private CouchbaseConfig couchbaseConfig;
public List<ArLedger> getBranchArLedgers(String branchId, String fromDate, String toDate) {
String query = Queries.GET_AR_LEDGER_BY_BRANCH_AND_DATE_RANGE;
query = MessageFormat.format(query, branchId, fromDate, toDate);
Cluster cluster = null;
try {
cluster = couchbaseConfig.connectToCouchbase();
QueryResult queryResult = cluster.query(query);
return queryResult.rowsAs(ArLedger.class);
} catch (Exception e) {
e.printStackTrace();
return Collections.emptyList();
} finally {
if (cluster != null) {
cluster.disconnect();
}
}
}
以及注入的 CouchbaseConfig 中的 connectToCouchbase():
@Value("${app.couchbase.connection-string}")
private String connectionString;
@Value("${app.couchbase.username}")
private String username;
@Value("${app.couchbase.password}")
private String password;
public Cluster connectToCouchbase() {
return Cluster.connect(connectionString, username, password);
}
编辑 2:更新代码以遵循 dnault 的建议,以及运行代码时出现的错误的屏幕截图:
沙发底座配置:
@Configuration
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {
@Autowired
private ApplicationContext context;
@Value("${app.couchbase.connection-string}")
private String connectionString;
@Value("${app.couchbase.username}")
private String username;
@Value("${app.couchbase.password}")
private String password;
@Bean
public Cluster couchbaseCluster() {
return Cluster.connect(connectionString, username, password);
}
}
存储库代码:
@Repository
public class ArLedgerRepository {
@Autowired
private Cluster couchbaseCluster;
public List<ArLedger> getAllBranchArLedgers(String branchId, String fromDate, String toDate) {
String query = Queries.GET_ALL_AR_LEDGERS_BY_BRANCH_AND_DATE_RANGE;
query = MessageFormat.format(query, branchId, fromDate, toDate);
try {
QueryResult queryResult = couchbaseCluster.query(query);
return queryResult.rowsAs(ArLedger.class);
} catch (Exception e) {
e.printStackTrace();
return Collections.emptyList();
} finally {
couchbaseCluster.disconnect();
}
}
}
@kei101895
AbstractCouchbaseConfiguration 中已经定义了一个 couchbaseCluster bean。 如果我没记错的话,那是@Autowired 将使用的集群(我相信是因为其他@Beans 之前需要它并且已经创建了)。
该 couchbaseCluster 使用指定了 destroyMethod 的 couchbaseClusterEnvironment bean。 这将确保在 ClusterEnvironment 上调用 shutdown()
@Bean(destroyMethod = "shutdown")
public ClusterEnvironment couchbaseClusterEnvironment() {...
要为提供的 Cluster @Bean 自定义环境,可以在 couchbase 配置 class 中 @Override configureEnvironment(builder) 方法。
如果您真的想要/需要拥有自己的 Cluster bean,您可以在 @Bean("myBeanName") 中给它起一个名字,然后用以下方法引用它:
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class); myCluster = (Cluster) ac.getBean("myBeanName");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.