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

发布于 2021-10-28 11:42:45
虽然finalize()方法在Java9之后就被弃用了,但是如果我们使用的是jaxb,那么jaxb库仍然使用finalize.So,这样就会发生内存泄漏。你可以通过this了解更多信息。
https://stackoverflow.com/questions/69750511
复制相似问题