首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spring webServiceTemplate和jaxb库会导致«java.lang.ref.Finalizer»的内存泄漏

使用Spring webServiceTemplate和jaxb库会导致«java.lang.ref.Finalizer»的内存泄漏
EN

Stack Overflow用户
提问于 2021-10-28 08:14:25
回答 1查看 152关注 0票数 0

我在我的多线程应用程序(10个线程)中执行webServiceTemplate.marshalSendAndReceive,它导致了终结器类的内存泄漏。我在调试时发现了哪些类在其实现中使用了finalize。在大多数情况下,它是UnmarshallerImpl和HttpsURLConnectionImpl。Jaxb2Marshaller为每个请求创建新的UnmarshallerImpl实例,正如我所发现的,GC不能删除这个对象,直到低优先级线程为每个实例执行finalize()。显然,FinalizerThread不能及时处理这个对象的队列,也不能释放内存。当我模拟调用webServiceTemplate.marshalSendAndReceive的方法时,内存泄漏的问题就消失了。有没有办法解决这个问题?

下面是我的WebServise配置:

代码语言:javascript
复制
@Configuration
public class WebServiceConfig {
    private final Props props;
    private final ApplicationProps applicationProps;

    public WebServiceConfig(@NotNull final Props props, @NotNull final ApplicationProps applicationProps) {
        this.props = props;
        this.applicationProps = applicationProps;
    }

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setPackagesToScan(applicationProps.getPackagesToScan());
        return marshaller;
    }

    @Bean
    public WebServiceTemplate webServiceTemplate(final WebServiceTemplateBuilder builder, final AllTimeouts allTimeouts) {
        return builder
                .setMarshaller(marshaller())
                .setUnmarshaller(marshaller())
                .messageSenders(new BasicAuthHttpsConnectionMessageSender(
                        props.getUsername(),
                        props.getPassword(),
                        allTimeouts.getReadTimeout()))
                .build();
    }

}


public class BasicAuthHttpsConnectionMessageSender extends HttpsUrlConnectionMessageSender {
    private final String b64Creds;

    public BasicAuthHttpsConnectionMessageSender(final String username,
                                                 final String password,
                                                 final Integer readTimeout) {
        byte[] message;
        message = String.format("%s:%s", username, password).getBytes(StandardCharsets.UTF_8);
        b64Creds = DatatypeConverter.printBase64Binary(message);
        setReadTimeout(Duration.ofMillis(readTimeout));
    }

    @Override
    protected void prepareConnection(final HttpURLConnection connection) throws IOException {
        connection.setRequestProperty(HttpHeaders.AUTHORIZATION, String.format("Basic %s", b64Creds));
        super.prepareConnection(connection);
    }
}

以下是我的依赖项:

代码语言:javascript
复制
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
    implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
    implementation group: 'net.logstash.logback', name: 'logstash-logback-encoder', version: '4.10'
    compile('javax.xml.bind:jaxb-api:2.3.0')
    compile('javax.activation:activation:1.1')
    compile('org.glassfish.jaxb:jaxb-runtime:2.3.0')
    compile 'org.hibernate.validator:hibernate-validator:6.0.13.Final'
    compile group: 'org.postgresql', name: 'postgresql', version: '42.2.11'
    compile group: 'org.springframework.vault', name: 'spring-vault-core', version: '2.1.3.RELEASE'
    compile group: 'org.springframework.ws', name: 'spring-ws-security', version: '2.2.2.RELEASE'
    compile group: 'org.springframework.ws', name: 'spring-ws-support', version: '2.2.2.RELEASE'
    compile group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '2.1.8.RELEASE'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

EN

回答 1

Stack Overflow用户

发布于 2021-10-28 11:42:45

虽然finalize()方法在Java9之后就被弃用了,但是如果我们使用的是jaxb,那么jaxb库仍然使用finalize.So,这样就会发生内存泄漏。你可以通过this了解更多信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69750511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档