diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp
index 167339ec6c7e1b4a3520d1fd0bb96b975a842f40..b8c025536585a66eaa599c99293a8a9da39dcc8d 100644
--- a/Marlin/src/Marlin.cpp
+++ b/Marlin/src/Marlin.cpp
@@ -730,11 +730,7 @@ void setup() {
   // Load data from EEPROM if available (or use defaults)
   // This also updates variables in the planner, elsewhere
   (void)settings.load();
-  
-  #if ENABLED(PRINTCOUNTER)
-    print_job_timer.init();
-  #endif  
-  
+
   #if HAS_M206_COMMAND
     // Initialize current position based on home_offset
     COPY(current_position, home_offset);
@@ -747,6 +743,8 @@ void setup() {
 
   thermalManager.init();    // Initialize temperature loop
 
+  print_job_timer.init();   // Initial setup of print job timer
+
   stepper.init();    // Initialize stepper, this enables interrupts!
 
   #if HAS_SERVOS
diff --git a/Marlin/src/libs/stopwatch.cpp b/Marlin/src/libs/stopwatch.cpp
index 29f84099a60cda2887decad3ce6fe47510ca8310..cc9268645ee156350008c87db198e8bc99e4b74d 100644
--- a/Marlin/src/libs/stopwatch.cpp
+++ b/Marlin/src/libs/stopwatch.cpp
@@ -20,21 +20,23 @@
  *
  */
 
-#include "../Marlin.h"
 #include "stopwatch.h"
 
-Stopwatch::Stopwatch() {
-  this->reset();
-}
+#include "../inc/MarlinConfig.h"
+
+Stopwatch::State Stopwatch::state;
+millis_t Stopwatch::accumulator;
+millis_t Stopwatch::startTimestamp;
+millis_t Stopwatch::stopTimestamp;
 
 bool Stopwatch::stop() {
   #if ENABLED(DEBUG_STOPWATCH)
     Stopwatch::debug(PSTR("stop"));
   #endif
 
-  if (this->isRunning() || this->isPaused()) {
-    this->state = STOPPED;
-    this->stopTimestamp = millis();
+  if (isRunning() || isPaused()) {
+    state = STOPPED;
+    stopTimestamp = millis();
     return true;
   }
   else return false;
@@ -45,9 +47,9 @@ bool Stopwatch::pause() {
     Stopwatch::debug(PSTR("pause"));
   #endif
 
-  if (this->isRunning()) {
-    this->state = PAUSED;
-    this->stopTimestamp = millis();
+  if (isRunning()) {
+    state = PAUSED;
+    stopTimestamp = millis();
     return true;
   }
   else return false;
@@ -58,12 +60,12 @@ bool Stopwatch::start() {
     Stopwatch::debug(PSTR("start"));
   #endif
 
-  if (!this->isRunning()) {
-    if (this->isPaused()) this->accumulator = this->duration();
-    else this->reset();
+  if (!isRunning()) {
+    if (isPaused()) accumulator = duration();
+    else reset();
 
-    this->state = RUNNING;
-    this->startTimestamp = millis();
+    state = RUNNING;
+    startTimestamp = millis();
     return true;
   }
   else return false;
@@ -74,23 +76,23 @@ void Stopwatch::reset() {
     Stopwatch::debug(PSTR("reset"));
   #endif
 
-  this->state = STOPPED;
-  this->startTimestamp = 0;
-  this->stopTimestamp = 0;
-  this->accumulator = 0;
+  state = STOPPED;
+  startTimestamp = 0;
+  stopTimestamp = 0;
+  accumulator = 0;
 }
 
 bool Stopwatch::isRunning() {
-  return (this->state == RUNNING) ? true : false;
+  return (state == RUNNING) ? true : false;
 }
 
 bool Stopwatch::isPaused() {
-  return (this->state == PAUSED) ? true : false;
+  return (state == PAUSED) ? true : false;
 }
 
 millis_t Stopwatch::duration() {
-  return (((this->isRunning()) ? millis() : this->stopTimestamp)
-          - this->startTimestamp) / 1000UL + this->accumulator;
+  return (((isRunning()) ? millis() : stopTimestamp)
+          - startTimestamp) / 1000UL + accumulator;
 }
 
 #if ENABLED(DEBUG_STOPWATCH)
diff --git a/Marlin/src/libs/stopwatch.h b/Marlin/src/libs/stopwatch.h
index 4a1cdcfcf59cb623a21e924eaf925327044ab7cb..c39288c291828e64cadfca744c372ac156088893 100644
--- a/Marlin/src/libs/stopwatch.h
+++ b/Marlin/src/libs/stopwatch.h
@@ -23,11 +23,12 @@
 #ifndef STOPWATCH_H
 #define STOPWATCH_H
 
-#include "../core/types.h"
-
 // Print debug messages with M111 S2 (Uses 156 bytes of PROGMEM)
 //#define DEBUG_STOPWATCH
 
+#include "../core/macros.h"
+#include "../core/types.h"
+
 /**
  * @brief Stopwatch class
  * @details This class acts as a timer proving stopwatch functionality including
@@ -41,21 +42,16 @@ class Stopwatch {
       PAUSED
     };
 
-    Stopwatch::State state;
-    millis_t accumulator;
-    millis_t startTimestamp;
-    millis_t stopTimestamp;
+    static Stopwatch::State state;
+    static millis_t accumulator;
+    static millis_t startTimestamp;
+    static millis_t stopTimestamp;
 
   public:
-    /**
-     * @brief Class constructor
-     */
-    Stopwatch();
-
     /**
      * @brief Initialize the stopwatch
      */
-    inline void init() {}
+    FORCE_INLINE static void init() { reset(); }
 
     /**
      * @brief Stops the stopwatch
@@ -63,56 +59,56 @@ class Stopwatch {
      * no timer is currently running.
      * @return true is method was successful
      */
-    bool stop();
+    static bool stop();
 
     /**
      * @brief Pause the stopwatch
-     * @details Pauses the running timer, it will silently ignore the request if
+     * @details Pause the running timer, it will silently ignore the request if
      * no timer is currently running.
      * @return true is method was successful
      */
-    bool pause();
+    static bool pause();
 
     /**
-     * @brief Starts the stopwatch
-     * @details Starts the timer, it will silently ignore the request if the
+     * @brief Start the stopwatch
+     * @details Start the timer, it will silently ignore the request if the
      * timer is already running.
      * @return true is method was successful
      */
-    bool start();
+    static bool start();
 
     /**
-     * @brief Resets the stopwatch
-     * @details Resets all settings to their default values.
+     * @brief Reset the stopwatch
+     * @details Reset all settings to their default values.
      */
-    void reset();
+    static void reset();
 
     /**
-     * @brief Checks if the timer is running
-     * @details Returns true if the timer is currently running, false otherwise.
+     * @brief Check if the timer is running
+     * @details Return true if the timer is currently running, false otherwise.
      * @return true if stopwatch is running
      */
-    bool isRunning();
+    static bool isRunning();
 
     /**
-     * @brief Checks if the timer is paused
-     * @details Returns true if the timer is currently paused, false otherwise.
+     * @brief Check if the timer is paused
+     * @details Return true if the timer is currently paused, false otherwise.
      * @return true if stopwatch is paused
      */
-    bool isPaused();
+    static bool isPaused();
 
     /**
-     * @brief Gets the running time
-     * @details Returns the total number of seconds the timer has been running.
+     * @brief Get the running time
+     * @details Return the total number of seconds the timer has been running.
      * @return the delta since starting the stopwatch
      */
-    millis_t duration();
+    static millis_t duration();
 
     #ifdef DEBUG_STOPWATCH
 
       /**
-       * @brief Prints a debug message
-       * @details Prints a simple debug message "Stopwatch::function"
+       * @brief Print a debug message
+       * @details Print a simple debug message "Stopwatch::function"
        */
       static void debug(const char func[]);
 
diff --git a/Marlin/src/module/printcounter.cpp b/Marlin/src/module/printcounter.cpp
index 32e4d83212b7f350ce61110a9260714ab68a589b..66c6f2fbc48043ef0b4d1122d25611599b28ebf0 100644
--- a/Marlin/src/module/printcounter.cpp
+++ b/Marlin/src/module/printcounter.cpp
@@ -22,74 +22,84 @@
 
 #include "../inc/MarlinConfig.h"
 
-#if ENABLED(PRINTCOUNTER)
+#if DISABLED(PRINTCOUNTER)
 
-#include "printcounter.h"
+#include "../libs/stopwatch.h"
+Stopwatch print_job_timer;      // Global Print Job Timer instance
 
+#else // PRINTCOUNTER
+
+#include "printcounter.h"
 #include "../Marlin.h"
 
+PrintCounter print_job_timer;   // Global Print Job Timer instance
+
+printStatistics PrintCounter::data;
+
+const PrintCounter::promdress PrintCounter::address = STATS_EEPROM_ADDRESS;
+
+const uint16_t PrintCounter::updateInterval = 10;
+const uint16_t PrintCounter::saveInterval = 3600;
+millis_t PrintCounter::lastDuration;
+bool PrintCounter::loaded = false;
+
 millis_t PrintCounter::deltaDuration() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("deltaDuration"));
+    debug(PSTR("deltaDuration"));
   #endif
 
-  millis_t tmp = this->lastDuration;
-  this->lastDuration = this->duration();
-  return this->lastDuration - tmp;
-}
-
-bool PrintCounter::isLoaded() {
-  return this->loaded;
+  millis_t tmp = lastDuration;
+  lastDuration = duration();
+  return lastDuration - tmp;
 }
 
 void PrintCounter::incFilamentUsed(double const &amount) {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("incFilamentUsed"));
+    debug(PSTR("incFilamentUsed"));
   #endif
 
   // Refuses to update data if object is not loaded
-  if (!this->isLoaded()) return;
+  if (!isLoaded()) return;
 
-  this->data.filamentUsed += amount; // mm
+  data.filamentUsed += amount; // mm
 }
 
-
 void PrintCounter::initStats() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("initStats"));
+    debug(PSTR("initStats"));
   #endif
 
-  this->loaded = true;
-  this->data = { 0, 0, 0, 0, 0.0 };
+  loaded = true;
+  data = { 0, 0, 0, 0, 0.0 };
 
-  this->saveStats();
-  eeprom_write_byte((uint8_t *) this->address, 0x16);
+  saveStats();
+  eeprom_write_byte((uint8_t*)address, 0x16);
 }
 
 void PrintCounter::loadStats() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("loadStats"));
+    debug(PSTR("loadStats"));
   #endif
 
   // Checks if the EEPROM block is initialized
-  if (eeprom_read_byte((uint8_t *) this->address) != 0x16) this->initStats();
-  else eeprom_read_block(&this->data,
-    (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
+  if (eeprom_read_byte((uint8_t*)address) != 0x16) initStats();
+  else eeprom_read_block(&data,
+    (void*)(address + sizeof(uint8_t)), sizeof(printStatistics));
 
-  this->loaded = true;
+  loaded = true;
 }
 
 void PrintCounter::saveStats() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("saveStats"));
+    debug(PSTR("saveStats"));
   #endif
 
   // Refuses to save data if object is not loaded
-  if (!this->isLoaded()) return;
+  if (!isLoaded()) return;
 
   // Saves the struct to EEPROM
-  eeprom_update_block(&this->data,
-    (void *)(this->address + sizeof(uint8_t)), sizeof(printStatistics));
+  eeprom_update_block(&data,
+    (void*)(address + sizeof(uint8_t)), sizeof(printStatistics));
 }
 
 void PrintCounter::showStats() {
@@ -98,19 +108,19 @@ void PrintCounter::showStats() {
   SERIAL_PROTOCOLPGM(MSG_STATS);
 
   SERIAL_ECHOPGM("Prints: ");
-  SERIAL_ECHO(this->data.totalPrints);
+  SERIAL_ECHO(data.totalPrints);
 
   SERIAL_ECHOPGM(", Finished: ");
-  SERIAL_ECHO(this->data.finishedPrints);
+  SERIAL_ECHO(data.finishedPrints);
 
   SERIAL_ECHOPGM(", Failed: "); // Note: Removes 1 from failures with an active counter
-  SERIAL_ECHO(this->data.totalPrints - this->data.finishedPrints
-    - ((this->isRunning() || this->isPaused()) ? 1 : 0));
+  SERIAL_ECHO(data.totalPrints - data.finishedPrints
+    - ((isRunning() || isPaused()) ? 1 : 0));
 
   SERIAL_EOL();
   SERIAL_PROTOCOLPGM(MSG_STATS);
 
-  duration_t elapsed = this->data.printTime;
+  duration_t elapsed = data.printTime;
   elapsed.toString(buffer);
 
   SERIAL_ECHOPGM("Total time: ");
@@ -118,11 +128,11 @@ void PrintCounter::showStats() {
 
   #if ENABLED(DEBUG_PRINTCOUNTER)
     SERIAL_ECHOPGM(" (");
-    SERIAL_ECHO(this->data.printTime);
+    SERIAL_ECHO(data.printTime);
     SERIAL_CHAR(')');
   #endif
 
-  elapsed = this->data.longestPrint;
+  elapsed = data.longestPrint;
   elapsed.toString(buffer);
 
   SERIAL_ECHOPGM(", Longest job: ");
@@ -130,7 +140,7 @@ void PrintCounter::showStats() {
 
   #if ENABLED(DEBUG_PRINTCOUNTER)
     SERIAL_ECHOPGM(" (");
-    SERIAL_ECHO(this->data.longestPrint);
+    SERIAL_ECHO(data.longestPrint);
     SERIAL_CHAR(')');
   #endif
 
@@ -138,14 +148,14 @@ void PrintCounter::showStats() {
   SERIAL_PROTOCOLPGM(MSG_STATS);
 
   SERIAL_ECHOPGM("Filament used: ");
-  SERIAL_ECHO(this->data.filamentUsed / 1000);
+  SERIAL_ECHO(data.filamentUsed / 1000);
   SERIAL_CHAR('m');
 
   SERIAL_EOL();
 }
 
 void PrintCounter::tick() {
-  if (!this->isRunning()) return;
+  if (!isRunning()) return;
 
   static uint32_t update_last = millis(),
                   eeprom_last = millis();
@@ -153,37 +163,37 @@ void PrintCounter::tick() {
   millis_t now = millis();
 
   // Trying to get the amount of calculations down to the bare min
-  const static uint16_t i = this->updateInterval * 1000;
+  const static uint16_t i = updateInterval * 1000;
 
   if (now - update_last >= i) {
     #if ENABLED(DEBUG_PRINTCOUNTER)
-      PrintCounter::debug(PSTR("tick"));
+      debug(PSTR("tick"));
     #endif
 
-    this->data.printTime += this->deltaDuration();
+    data.printTime += deltaDuration();
     update_last = now;
   }
 
   // Trying to get the amount of calculations down to the bare min
-  const static millis_t j = this->saveInterval * 1000;
+  const static millis_t j = saveInterval * 1000;
   if (now - eeprom_last >= j) {
     eeprom_last = now;
-    this->saveStats();
+    saveStats();
   }
 }
 
 // @Override
 bool PrintCounter::start() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("start"));
+    debug(PSTR("start"));
   #endif
 
-  bool paused = this->isPaused();
+  bool paused = isPaused();
 
   if (super::start()) {
     if (!paused) {
-      this->data.totalPrints++;
-      this->lastDuration = 0;
+      data.totalPrints++;
+      lastDuration = 0;
     }
     return true;
   }
@@ -194,17 +204,17 @@ bool PrintCounter::start() {
 // @Override
 bool PrintCounter::stop() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("stop"));
+    debug(PSTR("stop"));
   #endif
 
   if (super::stop()) {
-    this->data.finishedPrints++;
-    this->data.printTime += this->deltaDuration();
+    data.finishedPrints++;
+    data.printTime += deltaDuration();
 
-    if (this->duration() > this->data.longestPrint)
-      this->data.longestPrint = this->duration();
+    if (duration() > data.longestPrint)
+      data.longestPrint = duration();
 
-    this->saveStats();
+    saveStats();
     return true;
   }
   else return false;
@@ -213,11 +223,11 @@ bool PrintCounter::stop() {
 // @Override
 void PrintCounter::reset() {
   #if ENABLED(DEBUG_PRINTCOUNTER)
-    PrintCounter::debug(PSTR("stop"));
+    debug(PSTR("stop"));
   #endif
 
   super::reset();
-  this->lastDuration = 0;
+  lastDuration = 0;
 }
 
 #if ENABLED(DEBUG_PRINTCOUNTER)
@@ -231,12 +241,4 @@ void PrintCounter::reset() {
   }
 #endif
 
-
-PrintCounter print_job_timer = PrintCounter();
-
-#else
-
-#include "../libs/stopwatch.h"
-Stopwatch print_job_timer = Stopwatch();
-
 #endif // PRINTCOUNTER
diff --git a/Marlin/src/module/printcounter.h b/Marlin/src/module/printcounter.h
index 640d505c58255512567266fbd3f41416d6bf0b2d..db6f74606f4c74c960255db51e65db1c9476cf95 100644
--- a/Marlin/src/module/printcounter.h
+++ b/Marlin/src/module/printcounter.h
@@ -23,13 +23,20 @@
 #ifndef PRINTCOUNTER_H
 #define PRINTCOUNTER_H
 
-#include "../inc/MarlinConfig.h"
 #include "../libs/stopwatch.h"
 #include "../libs/duration_t.h"
+#include "../inc/MarlinConfig.h"
 
 // Print debug messages with M111 S2
 //#define DEBUG_PRINTCOUNTER
 
+#if ENABLED(I2C_EEPROM) || ENABLED(SPI_EEPROM)
+  // round up address to next page boundary (assuming 32 byte pages)
+  #define STATS_EEPROM_ADDRESS 0x40
+#else
+  #define STATS_EEPROM_ADDRESS 0x32
+#endif
+
 struct printStatistics {    // 16 bytes (20 with real doubles)
   //const uint8_t magic;    // Magic header, it will always be 0x16
   uint16_t totalPrints;     // Number of prints
@@ -43,20 +50,20 @@ class PrintCounter: public Stopwatch {
   private:
     typedef Stopwatch super;
 
-    printStatistics data;
+    #if ENABLED(I2C_EEPROM) || ENABLED(SPI_EEPROM) || defined(CPU_32_BIT)
+      typedef uint32_t promdress;
+    #else
+      typedef uint16_t promdress;
+    #endif
+
+    static printStatistics data;
 
     /**
      * @brief EEPROM address
      * @details Defines the start offset address where the data is stored.
      */
-    #if ENABLED(I2C_EEPROM) || ENABLED(SPI_EEPROM)
-      // round up address to next page boundary (assuming 32 byte pages)
-      const uint32_t address = 0x40;
-    #elif defined(CPU_32_BIT)
-      const uint32_t address = 0x32;
-    #else
-      const uint16_t address = 0x32;
-    #endif
+    static const promdress address;
+
     /**
      * @brief Interval in seconds between counter updates
      * @details This const value defines what will be the time between each
@@ -65,7 +72,7 @@ class PrintCounter: public Stopwatch {
      * @note The max value for this option is 60(s), otherwise integer
      * overflow will happen.
      */
-    const uint16_t updateInterval = 10;
+    static const uint16_t updateInterval;
 
     /**
      * @brief Interval in seconds between EEPROM saves
@@ -73,114 +80,114 @@ class PrintCounter: public Stopwatch {
      * EEPROM save cycle, the development team recommends to set this value
      * no lower than 3600 secs (1 hour).
      */
-    const uint16_t saveInterval = 3600;
+    static const uint16_t saveInterval;
 
     /**
      * @brief Timestamp of the last call to deltaDuration()
-     * @details Stores the timestamp of the last deltaDuration(), this is
+     * @details Store the timestamp of the last deltaDuration(), this is
      * required due to the updateInterval cycle.
      */
-    millis_t lastDuration;
+    static millis_t lastDuration;
 
     /**
-     * @brief Stats were loaded from EERPROM
+     * @brief Stats were loaded from EEPROM
      * @details If set to true it indicates if the statistical data was already
      * loaded from the EEPROM.
      */
-    bool loaded = false;
+    static bool loaded;
 
   protected:
     /**
      * @brief dT since the last call
-     * @details Returns the elapsed time in seconds since the last call, this is
+     * @details Return the elapsed time in seconds since the last call, this is
      * used internally for print statistics accounting is not intended to be a
      * user callable function.
      */
-    millis_t deltaDuration();
+    static millis_t deltaDuration();
 
   public:
 
     /**
      * @brief Initialize the print counter
      */
-    inline void init() {
+    static inline void init() {
       super::init();
-      this->loadStats();
+      loadStats();
     }
 
     /**
-     * @brief Checks if Print Statistics has been loaded
-     * @details Returns true if the statistical data has been loaded.
+     * @brief Check if Print Statistics has been loaded
+     * @details Return true if the statistical data has been loaded.
      * @return bool
      */
-    bool isLoaded();
+    FORCE_INLINE static bool isLoaded() { return loaded; }
 
     /**
-     * @brief Increments the total filament used
+     * @brief Increment the total filament used
      * @details The total filament used counter will be incremented by "amount".
      *
      * @param amount The amount of filament used in mm
      */
-    void incFilamentUsed(double const &amount);
+    static void incFilamentUsed(double const &amount);
 
     /**
-     * @brief Resets the Print Statistics
-     * @details Resets the statistics to zero and saves them to EEPROM creating
+     * @brief Reset the Print Statistics
+     * @details Reset the statistics to zero and saves them to EEPROM creating
      * also the magic header.
      */
-    void initStats();
+    static void initStats();
 
     /**
-     * @brief Loads the Print Statistics
-     * @details Loads the statistics from EEPROM
+     * @brief Load the Print Statistics
+     * @details Load the statistics from EEPROM
      */
-    void loadStats();
+    static void loadStats();
 
     /**
-     * @brief Saves the Print Statistics
-     * @details Saves the statistics to EEPROM
+     * @brief Save the Print Statistics
+     * @details Save the statistics to EEPROM
      */
-    void saveStats();
+    static void saveStats();
 
     /**
      * @brief Serial output the Print Statistics
      * @details This function may change in the future, for now it directly
      * prints the statistical data to serial.
      */
-    void showStats();
+    static void showStats();
 
     /**
      * @brief Return the currently loaded statistics
      * @details Return the raw data, in the same structure used internally
      */
-    printStatistics getStats() { return this->data; }
+    static printStatistics getStats() { return data; }
 
     /**
      * @brief Loop function
      * @details This function should be called at loop, it will take care of
      * periodically save the statistical data to EEPROM and do time keeping.
      */
-    void tick();
+    static void tick();
 
     /**
      * The following functions are being overridden
      */
-    bool start();
-    bool stop();
-    void reset();
+    static bool start();
+    static bool stop();
+    static void reset();
 
     #if ENABLED(DEBUG_PRINTCOUNTER)
 
       /**
-       * @brief Prints a debug message
-       * @details Prints a simple debug message "PrintCounter::function"
+       * @brief Print a debug message
+       * @details Print a simple debug message
        */
       static void debug(const char func[]);
 
     #endif
 };
 
-// Print Job Timer
+// Global Print Job Timer instance
 #if ENABLED(PRINTCOUNTER)
   extern PrintCounter print_job_timer;
 #else