Disclaimer: The String class has undergone multiple changes to improve performance and space utilization. What happens when JIT compiles code is then entirely undefined. The following is a simplification, and ignores any optimizations that may or may not be applied.
String is a class that encapsulates a char[]. The array length is always exactly the length() of the string. The class, and the underlying array, is immutable.
class String {
    private final char[] arr;
}
StringBuilder (and StringBuffer) is another class that encapsulates a char[], but the array is almost always larger than the number of characters in the array. The class, and the array, is mutable.
class StringBuilder {
    private char[] arr;
    private int len;
}
When you do string concatenation with the + operator, the compiler generates that as:
// Java code
s = s1 + s2 + s3;
// Generated code
s = new StringBuilder().append(s1).append(s2).append(s3).toString();
StringBuilder will initially create the array with length 16, and will re-allocate the array when needed. Worst case is that s1, s2, and s3 are all too large for the current array, so each append() call needs to re-size the array.
This means that the would progress as follows:
- new StringBuilder()- Creates- char[16].
 
- append(s1)- Resizes- arr, then copies chars from- s1.arrto the array.
 
- append(s2)- Resizes- arr, copies existing content (chars from- s1) to new array, then copies chars from- s2.arrto the array.
 
- append(s3)- Resizes- arr, copies existing content (chars from- s1and- s2) to new array, then copies chars from- s3.arrto the array.
 
- toString()- Create new- Stringwith- char[]sized to exactly fit the characters in the- StringBuilder, then copies the content (chars from- s1,- s2, and- s3) to the new- String.
 
All-in-all the chars from s1 ends up being copied 4 times.
If the string concatenation is S1 + S2, like in the question, then the characters from S1 are copied 2 or 3 times, and the characters from S2 are copied 2 times.
Since time complexity is generally worst case, that means O(3m + 2n), not the O(2m + n) suggested in the question. Of course, Big-O eliminates constant factors, so it is actually O(m + n).