我有 2 个应用程序。应用程序 1 使用的是 JHipster 5.8.2,我将其部署到具有 2GB RAM 的数字海洋液滴中,在将我的图像推送到 gitlab 的注册表后,我docker-compose -f app.yml up
运行它(它有_JAVA_OPTIONS=-Xmx512m -Xms256m
),一切都在大约 45 秒内完美运行。
应用程序 2 是用 JHipster 6.0.1 生成的(它实际上是我的应用程序 1 的升级)。我在应用程序 1 中使用了类似的 2 微滴:具有 2GB RAM 的单核,但由于Java Heap Space
而失败。在此之后,我将我的快捷批处理更改为 4GB 2 核心快捷批处理,并将我的app.yml
配置更改为:_JAVA_OPTIONS=-Xmx3072m -Xms2048m
但它仍然失败并出现相同的问题,并且在 40 分钟后。
出现此错误后,我尝试在计算机中以32GB运行图像,2 1/2小时后,出现了相同的问题。
这就是我打包 6.0.1 应用程序的方式:
/mvnw verify -Pprod -DskipTests
./mvnw jib:build -Dimage=registry.gitlab.com/amatos/project
在我的液滴中:
docker-compose -f app.yml up -d
这应该有效,但它永远不会通过线路Web application fully configured
几分钟后(取决于 RAM 的数量),它会失败。
我是否缺少额外的步骤?
发现:
经过大量测试,我发现,通过添加自定义 DTO,我遇到了 Java 堆空间问题。
生成的 DTO:
package com.facturapp.service.dto;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Lob;
/**
* A DTO for the {@link com.facturapp.domain.Address} entity.
*/
public class AddressDTO implements Serializable {
private Long id;
@NotNull
private String name;
private String contact;
private String mobile;
private String address;
@Lob
private String note;
private Boolean delivery;
private Boolean invoicing;
private Boolean active;
private Long districtId;
private String districtName;
private Long partnerId;
private String partnerName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Boolean isDelivery() {
return delivery;
}
public void setDelivery(Boolean delivery) {
this.delivery = delivery;
}
public Boolean isInvoicing() {
return invoicing;
}
public void setInvoicing(Boolean invoicing) {
this.invoicing = invoicing;
}
public Boolean isActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Long getDistrictId() {
return districtId;
}
public void setDistrictId(Long districtId) {
this.districtId = districtId;
}
public String getDistrictName() {
return districtName;
}
public void setDistrictName(String districtName) {
this.districtName = districtName;
}
public Long getPartnerId() {
return partnerId;
}
public void setPartnerId(Long partnerId) {
this.partnerId = partnerId;
}
public String getPartnerName() {
return partnerName;
}
public void setPartnerName(String partnerName) {
this.partnerName = partnerName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AddressDTO addressDTO = (AddressDTO) o;
if (addressDTO.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), addressDTO.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "AddressDTO{" +
"id=" + getId() +
", name='" + getName() + "'" +
", contact='" + getContact() + "'" +
", mobile='" + getMobile() + "'" +
", address='" + getAddress() + "'" +
", note='" + getNote() + "'" +
", delivery='" + isDelivery() + "'" +
", invoicing='" + isInvoicing() + "'" +
", active='" + isActive() + "'" +
", district=" + getDistrictId() +
", district='" + getDistrictName() + "'" +
", partner=" + getPartnerId() +
", partner='" + getPartnerName() + "'" +
"}";
}
}
定制 DTO
package com.facturapp.service.dto;
import com.facturapp.domain.District;
/**
* A DTO for the {@link com.facturapp.domain.Address} entity.
*/
public class AddressFaDTO extends AddressDTO {
private District district;
public District getDistrict() {
return district;
}
public void setDistrict(District district) {
this.district = district;
}
}
自定义 DTO 已Address
并扩展生成的 DTO。生成的 DTO 有几个字段,其中 2 个是districtId (Long)
和districtName (String)
,但我的自定义 DTO 也有district (District)
。类District
有一个属性Province
,它也有Region
,它也具有Country
。因此,当我检索Address
时,我还得到了地区,省,地区和国家。
我的自定义资源调用自定义服务,该服务检索我的自定义 DTO 与学区和所有其他类。
如果我使用生成的 DTO,我没有问题,但是当我使用我的自定义 DTO 时,由于 Java 堆空间,应用程序无法运行并失败。
错误日志
facturapp_1 | 2019-06-03 06:56:20.395 INFO 1 --- [ restartedMain] com.almasoft.facturapp.FacturApp : Starting FacturApp on c40efbe18b21 with PID 1 (/app/classes started by root in /)
facturapp_1 | 2019-06-03 06:56:20.407 INFO 1 --- [ restartedMain] com.almasoft.facturapp.FacturApp : The following profiles are active: prod,swagger
facturapp_1 | 2019-06-03 06:56:45.918 WARN 1 --- [ restartedMain] i.g.j.c.liquibase.AsyncSpringLiquibase : Warning, Liquibase took more than 5 seconds to start up!
facturapp_1 | 2019-06-03 06:56:57.351 INFO 1 --- [ restartedMain] c.a.facturapp.config.WebConfigurer : Web application configuration, using profiles: prod
facturapp_1 | 2019-06-03 06:56:57.353 INFO 1 --- [ restartedMain] c.a.facturapp.config.WebConfigurer : Web application fully configured
facturapp_1 | WARNING: An illegal reflective access operation has occurred
facturapp_1 | WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils (file:/app/libs/spring-core-5.1.6.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
facturapp_1 | WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils
facturapp_1 | WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
facturapp_1 | WARNING: All illegal access operations will be denied in a future release
facturapp_1 | 2019-06-03 07:03:27.207 WARN 1 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is com.google.common.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
facturapp_1 | 2019-06-03 07:03:27.606 ERROR 1 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
facturapp_1 |
facturapp_1 | org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is com.google.common.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
facturapp_1 | at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:185)
facturapp_1 | at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53)
facturapp_1 | at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360)
facturapp_1 | at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158)
facturapp_1 | at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122)
facturapp_1 | at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:893)
facturapp_1 | at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:163)
facturapp_1 | at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
facturapp_1 | at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
facturapp_1 | at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
facturapp_1 | at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
facturapp_1 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
facturapp_1 | at com.facturapp.FacturApp.main(FacturApp.java:63)
facturapp_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
facturapp_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
facturapp_1 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
facturapp_1 | at java.base/java.lang.reflect.Method.invoke(Unknown Source)
facturapp_1 | at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
facturapp_1 | Caused by: com.google.common.util.concurrent.ExecutionError: java.lang.OutOfMemoryError: Java heap space
facturapp_1 | at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2049)
facturapp_1 | at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
facturapp_1 | at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3976)
facturapp_1 | at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4960)
facturapp_1 | at springfox.documentation.schema.CachingModelDependencyProvider.dependentModels(CachingModelDependencyProvider.java:58)
facturapp_1 | at springfox.documentation.schema.DefaultModelProvider.dependencies(DefaultModelProvider.java:128)
facturapp_1 | at springfox.documentation.schema.CachingModelProvider.dependencies(CachingModelProvider.java:68)
facturapp_1 | at springfox.documentation.spring.web.scanners.ApiModelReader.populateDependencies(ApiModelReader.java:136)
facturapp_1 | at springfox.documentation.spring.web.scanners.ApiModelReader.read(ApiModelReader.java:78)
facturapp_1 | at springfox.documentation.spring.web.scanners.ApiListingScanner.scan(ApiListingScanner.java:133)
facturapp_1 | at springfox.documentation.spring.web.scanners.ApiDocumentationScanner.scan(ApiDocumentationScanner.java:71)
facturapp_1 | at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.scanDocumentation(DocumentationPluginsBootstrapper.java:101)
facturapp_1 | at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:167)
facturapp_1 | at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)
facturapp_1 | ... 17 common frames omitted
facturapp_1 | Caused by: java.lang.OutOfMemoryError: Java heap space
facturapp_1 | at java.base/java.util.Arrays.copyOf(Unknown Source)
facturapp_1 | at java.base/java.util.ArrayList.grow(Unknown Source)
facturapp_1 | at java.base/java.util.ArrayList.addAll(Unknown Source)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromRegularType(DefaultModelDependencyProvider.java:207)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:183)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromRegularType(DefaultModelDependencyProvider.java:207)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:183)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromCollectionElementType(DefaultModelDependencyProvider.java:220)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromCollectionElementType(DefaultModelDependencyProvider.java:220)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromCollectionElementType(DefaultModelDependencyProvider.java:220)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:181)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.maybeFromRegularType(DefaultModelDependencyProvider.java:207)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedPropertiesAndFields(DefaultModelDependencyProvider.java:183)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.resolvedDependencies(DefaultModelDependencyProvider.java:120)
facturapp_1 | at springfox.documentation.schema.DefaultModelDependencyProvider.dependentModels(DefaultModelDependencyProvider.java:79)
facturapp_1 | at springfox.documentation.schema.CachingModelDependencyProvider$1.load(CachingModelDependencyProvider.java:50)
facturapp_1 | at springfox.documentation.schema.CachingModelDependencyProvider$1.load(CachingModelDependencyProvider.java:48)
facturapp_1 | at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
facturapp_1 | at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
facturapp_1 | at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
facturapp_1 | at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
facturapp_1 | at com.google.common.cache.LocalCache.get(LocalCache.java:3953)
facturapp_1 | at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3976)
我的问题是:
- 为什么我只是扩展一个简单的 DTO 会遇到这样的问题?
- 如何解决此问题?
我的错误是使用域类作为字段,而不是地址的DTO类。
问题仍然是为什么在启动应用程序时出现内存问题,而不是在调用使用错误类的方法时出现内存问题。