[英]GC and static final fields
We are working on an payment application based on spring-boot 2.5.6.我们正在开发基于 spring-boot 2.5.6 的支付应用程序。 The application is hosted on docker and launched on Java 14. We created an abstract class named GeneralEnum
which is @Embeddable
and contains two variables int type
and String value
.该应用程序托管在 docker 上,并在 Java 14 上启动。我们创建了一个名为GeneralEnum
的抽象 class,它是@Embeddable
并且包含两个变量int type
和String value
。 All enumeration classes extend this base class and define constants inside it.所有枚举类都扩展了这个基类 class 并在其中定义了常量。
This decision is made to customize enumeration used in whole layer of application.做出此决定是为了自定义在整个应用程序层中使用的枚举。 You can see one example in below:您可以在下面看到一个示例:
@Embeddable
public class ShapeEnum extends GeneralEnum {
public static final ShapeEnum CIRCLE = new ShapeEnum(0, 'Circle');
public static final ShapeEnum RECTANGLE = new ShapeEnum(1, 'Rectangle');
public ShapeEnum(int type, String value) {
super(type, value);
}
}
This class is used in entity layer as embedded variable as follow:这个 class 在实体层中用作嵌入变量,如下所示:
@Entity
public class Shape {
@Embedded
@AttributeOverride(name = "type", column = @Column(name = "shape_type"))
private ShapeEnum shapeType;
}
The system worked perfectly, but something wrong happens and the value
field of ShapeEnum.RECTANGLE changed to Circle and type
is changed to 0 (.,.) and after that system would fail (dumping RAM shown the change of value).该系统运行完美,但发生了一些错误,ShapeEnum.RECTANGLE 的value
字段更改为Circle , type
更改为 0 (.,.),之后系统将失败(转储 RAM 显示值的更改)。 As I tracked, the problem is occurred after running GC and when the ShapeEnum is not used for a while.正如我跟踪的那样,问题是在运行 GC 之后以及一段时间未使用 ShapeEnum 时发生的。
Would anyone make an idea what happens and how tackle this problem?谁能知道会发生什么以及如何解决这个问题? For now, restarting docker container causes the app will work properly.目前,重启 docker 容器会使应用程序正常运行。
Thanks in advance.提前致谢。
--------------- --------------
The dump for another class is (TicketStatus class) shown below.另一个 class 的转储是(TicketStatus 类),如下所示。 The highlighted part is changed without reason.突出显示的部分被无故更改。 The first and second constants' value and type are the same.第一个和第二个常量的值和类型相同。 I am sure that setValue and setType won't call in the source-code.我确信 setValue 和 setType 不会在源代码中调用。
OK, so first I will say what the problem is not.好的,首先我会说问题不是什么。
This problem is not caused by the garbage collector.这个问题不是由垃圾收集器引起的。 The GC doesn't change the values of variables. GC 不会更改变量的值。 Not static variables, and not instance variables.不是 static 个变量,也不是实例变量。 So it is not the GC that is causing the type
field of some ShapeEnum
that denotes a rectangle ( 1
) to change to a circle ( 0
).因此,不是 GC 导致某些表示矩形 ( 1
) 的ShapeEnum
的type
字段更改为圆形 ( 0
)。
You say:你说:
As I tracked, the problem is occurred after running GC and when the
ShapeEnum
is not used for a while.正如我跟踪的那样,问题是在运行 GC 之后以及一段时间未使用ShapeEnum
时发生的。
That statement is not conclusive evidence.该声明不是确凿的证据。 What you are actually (probably) saying is that you observed an object with type
of 0
when it should have been 1
... at some time after a GC run.你实际上(可能)说的是你观察到一个 object type
为0
而它应该是1
... 在 GC 运行后的某个时间。 You (probably) didn't observe the change actually happening, and you (probably) can't be sure that the value was correct immediately before the GC ran.您(可能)没有观察到实际发生的变化,并且您(可能)无法确定在 GC 运行之前该值是否正确。 In fact, you (probably) can't even be sure that the value was wrong immediately after the GC ran.事实上,您(可能)甚至无法确定在 GC 运行后该值是否立即错误。
(If you do have clear evidence rather than supposition, please add it to the question.) (如果您确实有明确的证据而不是假设,请将其添加到问题中。)
So what actually is causing this change?那么到底是什么导致了这种变化呢?
At this stage we can only guess.在这个阶段我们只能猜测。 My guess would be that:我的猜测是:
some part of your application is calling the setValue
method when it shouldn't, or您的应用程序的某些部分在不应该调用setValue
方法时调用,或者
you have multiple objects that represent the "enums" for (say) rectangle.你有多个对象代表(比如说)矩形的“枚举”。
It strikes me that your implementation of these ersatz enums is fragile.让我印象深刻的是,您对这些人造枚举的实现是脆弱的。 They should be (at least loosely) immutable.它们应该(至少松散地)不可变。 You probably alter the GeneralEnum
class to remove the setters, and make the type
and value
fields final
.您可能会更改GeneralEnum
class 以删除 setter,并将type
和value
字段设置为final
。
If the objects are immutable, you won't have to worry about something changing them.如果对象是不可变的,您就不必担心有什么东西会改变它们。 There would be other ways to get a ShapeEnum
with type == 1
and value.equals("Circle")
, but you wouldn't be able to break CIRCLE
or RECTANGLE
.还有其他方法可以获得type == 1
和ShapeEnum
value.equals("Circle")
的 ShapeEnum ,但您无法打破CIRCLE
或RECTANGLE
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.