I trace down to the while loop in nxml-forward-single-balanced-item:
(defun nxml-forward-single-balanced-item ()
(condition-case err
(goto-char (let ((end (nxml-token-after)))
(save-excursion
(while (eq xmltok-type 'space)
(goto-char end)
(setq end (nxml-token-after)))
(cond ((/= (point) xmltok-start)
In my test xml file, when the last comment char is deleted, `end' will be 65, then (nxml-token-after) also returns 65 , so this is a endless loop.