简体   繁体   English

GC 和 static 最终字段

[英]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 typeString 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字段更改为Circletype更改为 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 ) 的ShapeEnumtype字段更改为圆形 ( 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 type0而它应该是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,并将typevalue字段设置为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 == 1ShapeEnum value.equals("Circle")的 ShapeEnum ,但您无法打破CIRCLERECTANGLE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM