- 1 1. What Are OnInit and OnDeinit in MQL5?
- 2 2. How to Use OnInit and Its Basic Syntax
- 3 3. How to Use OnDeinit and Practice Cleanup Logic
- 4 4. Practical Design Combining OnInit and OnDeinit
- 4.1 4.1 Basic Design Pattern (Template)
- 4.2 4.2 Why This Design Matters (Structural Understanding)
- 4.3 4.3 How to Think About State Management (Important)
- 4.4 4.4 Common Design Mistakes in Real Projects
- 4.5 4.5 Important Practical Design Guidelines (Reproducibility First)
- 4.6 4.6 The Core Idea (Advanced View)
- 4.7 Key Takeaways from This Section
- 5 5. Beginner Pitfalls and How to Fix Them
- 5.1 5.1 Not Realizing That OnInit Has Failed
- 5.2 5.2 Not Knowing That OnDeinit Is Being Called
- 5.3 5.3 Not Knowing the Cause of CopyBuffer Errors
- 5.4 5.4 Problems Caused by Forgetting Resource Release
- 5.5 5.5 Writing Initialization Logic in OnTick
- 5.6 5.6 Ignoring reason and Making Debugging Impossible
- 5.7 5.7 Design That Does Not Consider Reinitialization
- 5.8 Key Takeaways from This Section
- 6 6. Complete Practical Template and Design Summary
- 7 7. FAQ
- 7.1 Q1. Can OnInit fail to execute?
- 7.2 Q2. When is OnDeinit called?
- 7.3 Q3. Is it okay to run heavy processing in OnInit?
- 7.4 Q4. Will the EA still work if OnDeinit does nothing?
- 7.5 Q5. What is the difference between OnInit and OnTick?
- 7.6 Q6. What causes CopyBuffer to fail?
- 7.7 Q7. Should I always use the reason parameter in OnDeinit?
- 7.8 Q8. Can OnInit run multiple times?
- 7.9 FAQ Summary (Practical Judgment)
1. What Are OnInit and OnDeinit in MQL5?
In MQL5, OnInit and OnDeinit are the most basic functions for controlling the lifecycle of an EA (Expert Advisor) or indicator, from startup to shutdown.
In short, their roles are as follows.
- OnInit: Initialization logic that runs only once at startup
- OnDeinit: Cleanup logic that runs when the program stops
If you do not understand these two functions correctly, the following problems can occur.
- The indicator does not work correctly
- Memory or handle resources are not released
- Problems occur when a VPS restarts
- The EA stops unexpectedly
In other words, this is one of the most important points directly tied to EA stability and reproducibility.
1.1 Role of OnInit (Initialization)
OnInit is a function that runs only once when an EA or indicator is attached to a chart.
It mainly handles the following tasks.
- Creating indicator handles, such as iMA
- Initializing arrays and variables
- Checking input parameters
- Setting the initial state
Basic Structure (Minimal Example)
int OnInit()
{
Print("Initialization started");
return(INIT_SUCCEEDED);
}
Important Points Beginners Often Miss
- Always return a value with the int type
- On success:
INIT_SUCCEEDED - On failure:
INIT_FAILED
Common Mistakes
- Not writing a return value, which can cause a compile error or unstable behavior
- Returning
INIT_SUCCEEDEDeven when an error occurs - Allowing OnTick to run even though initialization has failed
In real projects, the basic rule is: if initialization fails, stop immediately.
1.2 Role of OnDeinit (Cleanup)
OnDeinit is a function that runs when an EA or indicator is stopped.
It is mainly called in the following situations.
- When the EA is removed from the chart
- When MT5 is closed
- When the program is recompiled
- When parameters are changed
- When the chart is changed, such as the symbol or timeframe
Basic Structure
void OnDeinit(const int reason)
{
Print("Cleanup: reason=", reason);
}
Role
- Release indicator handles
- Delete objects such as lines and text
- Output logs
Common Mistakes
- Leaving it empty, which can cause resource leaks and unreleased memory
- Not releasing handles, which can cause issues during long-running operation
- Ignoring reason, which makes debugging difficult
Especially in VPS operation, the quality of cleanup logic has a major effect on stability.
1.3 Difference from OnTick (A Common Beginner Confusion)
The point that confuses beginners most often is the difference from OnTick.
| Function | Execution Timing | Purpose |
|---|---|---|
| OnInit | Once at startup | Initialization |
| OnTick | Every tick | Trading logic |
| OnDeinit | At shutdown | Cleanup |
Mental Model (Important)
Startup -> OnInit (once)
↓
Market running -> OnTick (thousands of times)
↓
Stop -> OnDeinit (once)
Common Misunderstandings
- Writing trade execution logic in OnInit: not recommended
- Creating indicators every time in OnTick: inefficient and likely to cause bugs
- Not using OnDeinit: long-term operation can break down
The correct design is:
Prepare in OnInit -> process in OnTick -> clean up in OnDeinit

Key Takeaways from This Section
- OnInit: initialization, once
- OnDeinit: cleanup, once
- OnTick: main processing, every tick
- Separating these three roles creates a stable EA
2. How to Use OnInit and Its Basic Syntax
OnInit is the initialization function that runs only once when an EA starts.
A design mistake here directly leads to EA bugs, incorrect behavior, or startup failure.
This section explains OnInit in a practical form you can use in real projects.
2.1 Basic Syntax (Sample Code)
The basic syntax of OnInit is as follows.
int OnInit()
{
// Initialization logic
return(INIT_SUCCEEDED);
}
Meaning of the Return Value (Important)
| Return Value | Meaning |
|---|---|
| INIT_SUCCEEDED | Initialization completed successfully -> the EA runs |
| INIT_FAILED | Initialization failed -> the EA stops |
Important Practical Points
- You can control whether the EA starts by using the return value
- Always return
INIT_FAILEDwhen an error occurs - This prevents an EA from running in a broken state
Bad Example (Common Mistake)
int OnInit()
{
// Even though initialization failed...
return(INIT_SUCCEEDED);
}
This is one of the most dangerous bugs
because it can cause behavior that is hard to diagnose.
2.2 Specific Examples of Initialization Tasks
OnInit is for preparation.
Its tasks can mainly be grouped into the following three categories.
1. Creating Indicator Handles
int ma_handle;
int OnInit()
{
ma_handle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("Failed to get iMA handle");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
Points
- Functions such as iMA return a handle, which is an identifier
- On failure, the result is
INVALID_HANDLE - Always check it
2. Initializing Arrays and Variables
double buffer[];
int OnInit()
{
ArraySetAsSeries(buffer, true); // Make it a time series array
ArrayResize(buffer, 100); // Allocate size
return(INIT_SUCCEEDED);
}
Points
- Uninitialized arrays can cause bugs
- Be aware of time series arrays, where the newest value is index 0
3. Validating Input Parameters
input int period = 20;
int OnInit()
{
if(period <= 0)
{
Print("period must be 1 or greater");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
Points
- Stop immediately when parameters are invalid
- Prevent an EA from running with abnormal values
2.3 Common Mistakes (Important)
OnInit can easily become a source of bugs.
The following issues are especially common.
1. Ignoring Handle Acquisition Failure
ma_handle = iMA(...);
// No check -> crash later
Result: an error occurs in CopyBuffer.
2. Not Outputting Print Logs
// The cause of the error is unknown
At minimum, add this.
Print("OnInit started");
3. Making Initialization Too Heavy
- Large loops
- Heavy calculations
- External processing
Result
- Delayed startup
- Instability in VPS environments
Countermeasure
- Move heavy processing across OnTick where appropriate
4. Not Using INIT_FAILED
This is the most common mistake.
// Letting the EA run even after failure
Correct approach
if(error)
{
return(INIT_FAILED);
}
2.4 Practical Template (Ready to Use)
int ma_handle;
int OnInit()
{
Print("OnInit started");
// Create handle
ma_handle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("Error: failed to get iMA handle");
return(INIT_FAILED);
}
Print("OnInit succeeded");
return(INIT_SUCCEEDED);
}
This is the minimum safe design pattern.
Key Takeaways from This Section
- OnInit is one-time preparation logic at startup
- The return value determines whether the EA lives or stops
- Handle acquisition and parameter checks are required
- Always return
INIT_FAILEDon error
3. How to Use OnDeinit and Practice Cleanup Logic
OnDeinit is the function that runs at the moment an EA or indicator stops.
It is often underestimated, but in real projects it directly affects stable operation, restart resilience, and bug prevention.
In short, OnDeinit has the following three roles.
- Release used resources, such as memory and handles
- Delete chart objects
- Log the stop reason for debugging
3.1 Basic Syntax (Understand the Meaning of reason)
void OnDeinit(const int reason)
{
Print("OnDeinit executed: reason=", reason);
}
What Is reason?
It is a code that indicates why the program stopped.
| Constant | Description |
|---|---|
| REASON_REMOVE | Removed from the chart |
| REASON_RECOMPILE | Recompiled |
| REASON_CHARTCHANGE | Symbol or timeframe changed |
| REASON_PARAMETERS | Parameters changed |
| REASON_ACCOUNT | Account changed |
| REASON_CLOSE | MT5 closed |
Practical Points
- Logging reason helps identify the cause of unexpected shutdowns
- This is especially important in VPS operation, where restarts and disconnections must be tracked
3.2 Releasing Handles (Most Important)
Handles created in OnInit must be released in OnDeinit.
Example: Indicator Handle
void OnDeinit(const int reason)
{
if(ma_handle != INVALID_HANDLE)
{
IndicatorRelease(ma_handle);
Print("iMA handle released");
}
}
Why This Is Necessary
- If a handle is not released, it remains in memory
- It can cause bugs or crashes during long-running operation
- The impact is especially noticeable in VPS environments
This is especially important in environments where the EA is restarted repeatedly.
3.3 Deleting Chart Objects
If the EA displays lines or text, those objects remain unless you delete them.
Example: Deleting Objects
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, 0, -1);
Print("Objects deleted");
}
Common Problems
- Unwanted objects remain on the chart
- Displays are duplicated after restart
- Visual bugs occur
The rule is simple: always clean up display objects.
3.4 Common Mistakes in Real Projects
1. Leaving OnDeinit Empty
void OnDeinit(const int reason)
{
// Do nothing
}
Problems
- Memory leaks
- Remaining objects
- No useful debugging information
2. Not Releasing Handles
Result
- CopyBuffer errors increase
- Long-term operation becomes unstable
3. Ignoring reason
Problems
- You cannot tell why the EA stopped
- You cannot trace VPS-related problems
4. Deleting Everything Every Time
ObjectsDeleteAll(0, 0, -1);
Caution
- This may also delete objects created by other indicators
Countermeasures
- Manage objects with a name prefix
- Delete only the objects created by your own EA
3.5 Practical Template (Safe Design)
void OnDeinit(const int reason)
{
Print("OnDeinit started reason=", reason);
// Release handle
if(ma_handle != INVALID_HANDLE)
{
IndicatorRelease(ma_handle);
Print("Handle released");
}
// Delete objects if needed
// ObjectsDeleteAll(0, 0, -1);
Print("OnDeinit finished");
}
This structure provides the minimum level of stability.
3.6 Importance in VPS Operation (Practical View)
OnDeinit is especially important in the following cases.
Cases
- VPS restart
- MT5 crash
- Network disconnection followed by reconnection
Problems That Can Occur
- Resources are not released
- State becomes inconsistent
- Abnormal behavior occurs when the EA restarts
Countermeasures
- Design OnInit and OnDeinit as a pair
- Assume the state must be reset
Key Takeaways from This Section
- OnDeinit is cleanup processing at shutdown
- Handle release is required and is the most important point
- Use reason to understand why the EA stopped
- If ignored, long-term operation can break down
4. Practical Design Combining OnInit and OnDeinit
Understanding OnInit and OnDeinit separately is not enough.
In real projects, a stable EA is created only when they are designed as a pair.
In short, the basic design is as follows.
- OnInit: secure resources and build the initial state
- OnTick: execute logic
- OnDeinit: release resources and reset state
By separating these three points, reproducibility, stability, and maintainability improve significantly.
4.1 Basic Design Pattern (Template)
First, here is a structure you can use directly in real projects.
int ma_handle;
// Initialization
int OnInit()
{
Print("OnInit started");
ma_handle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("Error: failed to get handle");
return(INIT_FAILED);
}
Print("OnInit succeeded");
return(INIT_SUCCEEDED);
}
// Main processing
void OnTick()
{
double buffer[];
if(CopyBuffer(ma_handle, 0, 0, 1, buffer) <= 0)
{
Print("CopyBuffer failed");
return;
}
double ma = buffer[0];
// Trading logic example
if(ma > Close[0])
{
// Sell condition, etc.
}
}
// Cleanup
void OnDeinit(const int reason)
{
Print("OnDeinit started reason=", reason);
if(ma_handle != INVALID_HANDLE)
{
IndicatorRelease(ma_handle);
}
Print("OnDeinit finished");
}
4.2 Why This Design Matters (Structural Understanding)
This design is not just a formality. It is risk management itself.
Bad Design (Common)
void OnTick()
{
int handle = iMA(...); // Created every time
}
Problems
- Handles are created endlessly
- Memory pressure increases
- Operation becomes unstable
Good Design
- Create once in OnInit
- Only use it in OnTick
- Release it in OnDeinit
Result
- Lower load
- Better reproducibility
- Fewer bugs
4.3 How to Think About State Management (Important)
In EA design, you must think about state.
What Is State?
- Handles
- Arrays
- Position information
- Flag variables
Principle
- OnInit creates the state
- OnTick uses the state
- OnDeinit destroys the state
Example: Flag Management
bool is_initialized = false;
int OnInit()
{
is_initialized = true;
return(INIT_SUCCEEDED);
}
void OnTick()
{
if(!is_initialized) return;
}
This prevents incorrect behavior before initialization is complete.
4.4 Common Design Mistakes in Real Projects
1. Writing Initialization in OnTick
Problem
- It runs every tick, which is wasteful, heavy, and bug-prone
2. Not Considering OnDeinit
Problem
- State breaks after restart
- Abnormal behavior occurs on a VPS
3. Overusing Global Variables
Problem
- The state becomes unclear
- Bugs become difficult to trace
4. Not Considering Reinitialization Cases
OnInit is executed again in the following cases.
- Parameter changes
- Timeframe changes
- Recompilation
In other words
- Design as if initialization can happen any number of times
4.5 Important Practical Design Guidelines (Reproducibility First)
1. Initialization Failure Means Immediate Stop
Do not run in an invalid state.
2. Manage Resources in Pairs
- Create -> release
- Allocate -> release
3. Reduce Side Effects
- Keep OnTick as close to pure processing as possible
4. Design for VPS Operation
- Restart
- Disconnection
- Reconnection
Build a structure that can handle all of them.
4.6 The Core Idea (Advanced View)
OnInit and OnDeinit are not just functions.
They are the lifecycle management of the EA itself.
Whether you understand this changes the following significantly.
- Bug rate
- Reproducibility
- Operational stability
Key Takeaways from This Section
- OnInit, OnTick, and OnDeinit must be designed separately
- Manage resources through creation and release
- Pay attention to state management
- Design with reinitialization in mind
5. Beginner Pitfalls and How to Fix Them
The syntax of OnInit and OnDeinit is simple, but in real projects, problems such as “it does not run” or “the bug has no clear cause” happen often.
This section organizes the issues beginners and intermediate developers actually face by cause, impact, and solution.
5.1 Not Realizing That OnInit Has Failed
Symptoms
- The EA does not run, and OnTick is not executed
- It looks like no error has occurred
Cause
- OnInit returns
INIT_FAILED - Or an internal error occurs
Typical Example
int OnInit()
{
int handle = iMA(...);
if(handle == INVALID_HANDLE)
{
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
Handle acquisition fails, so the EA does not start.
Solution
Print("OnInit started");
Print("handle=", handle);
Always output logs.
Practical Point
- When the EA does not run, suspect OnInit failure first
- Always check the Experts log
5.2 Not Knowing That OnDeinit Is Being Called
Symptoms
- The EA resets by itself
- State disappears
- Settings are not applied
Cause
OnDeinit occurs after the following operations.
- Timeframe change
- Symbol change
- Parameter change
- Recompilation
Solution
void OnDeinit(const int reason)
{
Print("OnDeinit reason=", reason);
}
This makes it visible when and why the EA stopped.
Practical Point
Design the EA as if it can be restarted any number of times.
5.3 Not Knowing the Cause of CopyBuffer Errors
Symptoms
- CopyBuffer fails
- Values cannot be retrieved
Cause (This Is the Cause in Most Cases)
- Handle acquisition failed in OnInit
- The handle is invalid, meaning INVALID_HANDLE
Bad Example
CopyBuffer(ma_handle, 0, 0, 1, buffer);
This runs even when ma_handle is invalid.
Solution
if(ma_handle == INVALID_HANDLE)
{
Print("Invalid handle");
return;
}
Practical Point
When CopyBuffer errors occur, check OnInit first.
5.4 Problems Caused by Forgetting Resource Release
Symptoms
- Operation becomes unstable over time
- The EA becomes heavy
- MT5 crashes
Cause
- IndicatorRelease is not called
- Handles keep increasing
Solution
void OnDeinit(const int reason)
{
if(ma_handle != INVALID_HANDLE)
{
IndicatorRelease(ma_handle);
}
}
Practical Point
This is almost required for VPS operation.
5.5 Writing Initialization Logic in OnTick
Symptoms
- Operation is slow
- Behavior is unstable
- Bugs are hard to understand
Bad Example
void OnTick()
{
int handle = iMA(...);
}
Problem
- A handle is created every tick
- Memory pressure increases
- The design is inefficient
Solution
Move it to OnInit.
Practical Point
Separate initialization into OnInit and processing into OnTick.
5.6 Ignoring reason and Making Debugging Impossible
Symptoms
- You do not know why the EA stopped
- You cannot trace VPS problems
Solution
Print("Stop reason=", reason);
Practical Point
- REASON_RECOMPILE -> recompilation
- REASON_CHARTCHANGE -> chart change
If you check the log, you can identify the cause.
5.7 Design That Does Not Consider Reinitialization
Symptoms
- The EA breaks after parameter changes
- The EA does not run after restart
Cause
- The initialization assumption is broken
- State remains unexpectedly
Solution
- Always return to the initial state in OnInit
- Completely reset in OnDeinit
Practical Point
Design as if startup and shutdown can happen any number of times.
Key Takeaways from This Section
- When the EA does not run, suspect OnInit first
- CopyBuffer errors are often handle problems
- OnDeinit is called frequently
- If initialization and processing are not separated, the design breaks down
- Design with VPS operation in mind
6. Complete Practical Template and Design Summary
Based on the points above, here is a safe design template you can use directly in real projects.
The goals are as follows.
- Prevent initialization mistakes
- Keep the EA stable during long-term VPS operation
- Create a structure that can be debugged
6.1 Complete Template (Ready to Use)
int ma_handle = INVALID_HANDLE;
// Initialization
int OnInit()
{
Print("OnInit started");
// Create indicator handle
ma_handle = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_SMA, PRICE_CLOSE);
if(ma_handle == INVALID_HANDLE)
{
Print("Error: failed to get iMA handle");
return(INIT_FAILED);
}
Print("OnInit succeeded");
return(INIT_SUCCEEDED);
}
// Main processing
void OnTick()
{
// Handle check
if(ma_handle == INVALID_HANDLE)
{
Print("Invalid handle");
return;
}
double buffer[];
// Get data
if(CopyBuffer(ma_handle, 0, 0, 1, buffer) <= 0)
{
Print("CopyBuffer failed");
return;
}
double ma = buffer[0];
// Sample logic
if(ma > Close[0])
{
// Sell condition example
}
}
// Cleanup
void OnDeinit(const int reason)
{
Print("OnDeinit started reason=", reason);
// Release handle
if(ma_handle != INVALID_HANDLE)
{
IndicatorRelease(ma_handle);
ma_handle = INVALID_HANDLE;
}
Print("OnDeinit finished");
}
6.2 Design Intent of This Template (Important)
1. Centralized State Management
int ma_handle = INVALID_HANDLE;
Manage state globally.
Make the invalid state explicit with INVALID_HANDLE.
2. Stop When Initialization Fails
return(INIT_FAILED);
Prevent operation in an invalid state.
Protect reproducibility.
3. Defensive Code in OnTick
if(ma_handle == INVALID_HANDLE)
{
return;
}
Stop safely even in an unexpected state.
4. Release and Reset
IndicatorRelease(ma_handle);
ma_handle = INVALID_HANDLE;
Prevent double release.
Support reinitialization.
6.3 Design Checklist for Real Projects
When you build an EA, check whether it satisfies the following points.
Initialization (OnInit)
- Handle acquisition is checked
- Parameters are validated
- INIT_FAILED is returned on error
Execution (OnTick)
- Initialization state is checked
- The return value of CopyBuffer is checked
- Unnecessary initialization is not performed
Shutdown (OnDeinit)
- Handles are released
- reason is output to the log
- State is reset
6.4 Common Design Failure Patterns
Pattern 1: It Runs but Is Unstable
Cause
- Insufficient error checks
- Handles are not released
Pattern 2: It Breaks After Restart
Cause
- The design leaves state behind
- OnDeinit is not handled
Pattern 3: It Stops for an Unknown Reason
Cause
- reason is not logged
- OnInit failure is overlooked
6.5 Best Design for Long-Term VPS Operation
Required Conditions
- Restart resilience, assuming OnInit can run again
- Memory management, with required release logic
- Log output, so causes can be traced
Practical Evaluation Criteria
- Does it stay stable for more than three consecutive days?
- Does it behave the same way after restart, meaning reproducibility?
- Can you identify the cause when an error occurs?
6.6 Core Summary (Advanced View)
OnInit and OnDeinit are not just functions.
They are EA lifecycle control.
If this design is wrong, the following can happen.
- The EA works in backtests but breaks in live operation
- It becomes unstable on a VPS
- Unknown bugs occur
When this part is designed correctly, the following improve.
- Stability becomes stronger
- Debugging becomes easier
- The EA can withstand real operation
Key Takeaways from This Section
- Use the template as the base for design
- Separate initialization, execution, and shutdown
- Be strict about state management and resource management
- Design with VPS operation in mind
7. FAQ
Q1. Can OnInit fail to execute?
A. In normal operation, OnInit is executed.
However, if INIT_FAILED is returned inside OnInit, OnTick will not run afterward.
In practice, when an EA does not run, first suspect that OnInit has failed.
Q2. When is OnDeinit called?
A. It is called when the EA stops or changes.
Common cases include the following.
- EA removal
- MT5 shutdown
- Recompilation
- Parameter changes
- Chart changes
It is called more often than many developers expect, so ignoring it is risky.
Q3. Is it okay to run heavy processing in OnInit?
A. In general, it is not recommended.
Reasons:
- Startup becomes slow
- It may become unstable in a VPS environment
It is safer to distribute heavy processing to OnTick or other appropriate logic.
Q4. Will the EA still work if OnDeinit does nothing?
A. It may work in the short term, but it can become a long-term problem.
- Memory leaks
- Increasing handles
- Instability
Especially for VPS operation, OnDeinit should be implemented.
Q5. What is the difference between OnInit and OnTick?
A. Their execution frequency and roles are completely different.
- OnInit: once, for initialization
- OnTick: every tick, for logic processing
Writing too much processing in OnInit or initializing resources in OnTick is a design mistake.
Q6. What causes CopyBuffer to fail?
A. In many cases, the cause is an OnInit failure.
- The handle is INVALID_HANDLE
- Initialization is incomplete
The shortest path is to review OnInit first when CopyBuffer errors occur.
Q7. Should I always use the reason parameter in OnDeinit?
A. In real projects, it is almost required.
Reasons:
- You can identify why the EA stopped
- It helps with VPS troubleshooting
Even logging it is valuable.
Q8. Can OnInit run multiple times?
A. Yes, it can.
It is executed again in the following cases.
- Parameter changes
- Timeframe changes
- Recompilation
It is risky to assume it only happens once.
You must design with reinitialization in mind.
FAQ Summary (Practical Judgment)
- Not running -> check OnInit
- Unstable -> check OnDeinit
- CopyBuffer error -> check the handle
- VPS operation -> lifecycle design is required