The important notion is that of closures and (in mathematics) of free and bound variables. Learn also more about λ-calculus (and Scheme).
In some crude sense, the global or static variables (and also the literal constants, and the directly called functions) in a C program are the only closed values in a C function. See also this answer.
In Java, the data inside objects can be thought as closed values. Notice that static
data belongs to the class (which is an object itself) so Java has no really global data (but read more about Java classloaders, including the primordial one of the JVM).
BTW, both closures (or lambda abstractions) and objects are mixing data with code.
Practically speaking, the client data passed to callbacks can be thought as closed values. In other words, a callback routine with its client data is a closure.
So you could consider closed values inside closures as somehow "global" -to the code of the closure- values.
Conversely, you don't need any global "data" segments or global variables once closures are first class and you have anonymous functions (ie lambda abstraction).
Read absolutely SICP, Lisp In Small Pieces, Programming Language Pragmatics. You could later also read the Dragon Book and the GC handbook.
(I strongly recommend taking a few weeks to read all these first three books before coding your VM)
So have first-class closures in your VM. Look also into the Lua & Neko & Guile & Parrot & Ocaml VMs (at least for inspiration) and SECD machine.
Once you have first class closures, you really want to have a garbage collector.