Description

From User:
When frequently terminating and re-initializing the FConstraintInstance, there appears to be a leak when cleaning up the disabled joint, which leads to an ever growing list that gets sorted every frame and slowly becomes so massive that performance is destroyed.

What appears to be happening (to paraphrase):
1. the joint is getting queued for deletion on the physics thread
2. the joint is then being disconnected from the capsule body (aka "particle")
3. the disconnect marks the joint as being "disabled"
4. the "FJointConstraintPhysicsProxy::DestroyOnPhysicsThread" function checks "IsValid", which says "no", causing it to never get cleaned up

Steps to Reproduce
  1. Create a new Third Person Template C++ project named "JointConstraintLeak" with Preview 2
  2. Navigate to 'C++ Classes/JointConstraintLeak' in the content browser then open 'JointConstraintLeakCharacter'
  3. Add these lines of code in the AJointConstraintLeakCharacter::AJointConstraintLeakCharacter() in the .cpp(~line 16):
    // GS-BEGIN: Joint constraint leak
    TOptional<FConstraintInstance> Constraint;
    virtual void Tick(float DT) override;
    // GS-END
  1. Add these lines of code as the last lines above the }; in the .h:
    // GS-BEGIN: Joint constraint leak
    PrimaryActorTick.bCanEverTick = true;
    // GS-END
  1. Add these lines of code at the bottom of the .cpp: 
    // code placeholder
    // GS-BEGIN: Joint constraint leak
    void AJointConstraintLeakCharacter::Tick(float DT)
    {
    if (!Constraint.IsSet()) {
    Constraint = FConstraintInstance{};
    Constraint->SetLinearXMotion(ELinearConstraintMotion::LCM_Free);
    Constraint->SetLinearYMotion(ELinearConstraintMotion::LCM_Free);
    Constraint->SetLinearZMotion(ELinearConstraintMotion::LCM_Free);
    Constraint->SetAngularTwistMotion(EAngularConstraintMotion::ACM_Locked);
    Constraint->SetAngularSwing1Motion(EAngularConstraintMotion::ACM_Locked);
    Constraint->SetAngularSwing2Motion(EAngularConstraintMotion::ACM_Locked);
    }Constraint->TermConstraint();
    Constraint->SetRefFrame(EConstraintFrame::Frame1, GetCapsuleComponent()->GetComponentTransform());
    Constraint->SetRefFrame(EConstraintFrame::Frame2, FTransform::Identity);
    Constraint->InitConstraint(nullptr, GetCapsuleComponent()->GetBodyInstance(), 1.0f, this);
    }
    // GS-END
  1. Save All in Visual Studio then back in the Editor press the 'Recompile and Reload' button in the lower right hand corner
  2. Place 'JointConstraintLeakCharacter' in the level
  3. In the Viewport select the Viewport Options button in the upper left hand side
  4. Enable 'Show FPS'
  5. Play in Editor
  6. Observe the FPS

Expected Results:
The FPS level out and remain steady.

Actual Results:
After a few minutes the FPS will begin to steadily decline.

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-147418 in the post.

2
Login to Vote

Fixed
ComponentUE - Simulation - Physics
Affects Versions5.0
Target Fix5.1
Fix Commit21267098
Main Commit21267098
CreatedMar 29, 2022
ResolvedAug 8, 2022
UpdatedAug 17, 2022