当前位置: 首页 > 知识库问答 >
问题:

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

仲孙翔飞
2023-03-14

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

以下是我的Web服务配置:

@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);
    }
}

这是我的家属:

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'
}

共有2个答案

叶鸿煊
2023-03-14

虽然finalize()方法在Java9之后被弃用,但jaxb库仍然使用finalize。因此,如果我们使用jaxb,就会发生内存泄漏。你可以通过这个来了解更多。

刘德义
2023-03-14

请考虑在<代码> WebService EtMePoT(…)中将调用替换为<代码> MARSCALARER()/<代码>代码>使用Spring注入bean:

    @Bean
    public WebServiceTemplate webServiceTemplate(
        final WebServiceTemplateBuilder builder,
        final AllTimeouts allTimeouts,
        final Jaxb2Marshaller marshaller) {

否则,调用webServiceTemplate会导致创建新的封送处理程序,跳过工厂方法Jaxb2Marshaller marshaller()

 类似资料:
  • 我有一些和等,但是我没有设置。你觉得会是那样吗? 你有什么想法或建议吗? PS:该应用程序在Ubuntu机器上运行 多谢.

  • 我想首先说,这是我第一次必须处理性能,因为这是我第一次开发一个android应用程序。 该应用程序是一个源代码编辑器,在这里你可以打开文件,修改它们,并将它们保存回来。该应用程序由4个部分组成: 导航器视图:包含打开文件的ListView和打开文件夹的TreeView。 代码视图容器:它保存包含实际代码的视图。 代码容器:这是一个小视图,包含一个文本视图和一个自定义EditText(由我扩展Edi

  • 我正在玩rxjava,发现如果在活动被销毁之前没有完成订阅,则存在内存泄漏的风险,因为“可观察对象保留对上下文的引用”。如果订阅没有取消订阅,则此类情况的演示之一如下所示。已销毁(来源:https://github.com/dlew/android-subscription-leaks/blob/master/app/src/main/java/net/danlew/rxsubscriptions

  • 严重:web应用程序[]创建了一个ThreadLocal,其键类型为[com.box.sdk.boxDateFormat$1](值为[com.box.sdk.boxDateFormat$1@275AB696])和值类型为[java.text.SimpleDateFormat](值为[java.text.SimpleDateFormat@faabb360]),但在web应用程序停止时未能删除它。线程

  • 问题内容: 我正在编写一个测试程序,如下所示: 当用户单击按钮A时,它将打开50个JFrame。 当用户单击按钮B时,它将放置所有通过单击按钮A显示的JFrame。 我发现单击按钮B后内存不会减少。我使用任务管理器(在Windows中为+ + ,并检查“ java”的内存使用情况)确定了这一点。 问题答案: 是的,没有办法,无法解决(不仅在Java PL中), 1)实际上,不要在运行时/运行时创建

  • 问题内容: 我认为我的Android动态壁纸存在内存泄漏。每当我旋转屏幕时,收集的内存垃圾量就会增加50kb,并且不会减少。我认为这可能是由预定的将来引起的,因此我将提出一个方案以查看是否是这种情况。 假设您有一个包含以下成员的类(我们称其为Foo)。 现在您设定了预定的未来 Future拥有对可运行对象的引用,而Runnable拥有对父Foo对象的引用。我不确定是否是这种情况,但是这个事实是否意