Also see Computing System, Computing Freedom, Computing Liberalism, Operating System, Programmers, Users, End-Users.
Firstly, it must be noted that not all components of a structure need be explicitly given to a constructor or returned by a destructor. Actually, for the sake of readability, but also because no system can be founded without (infinitely many) implicit axioms, most of the times, many parameters are left implicit, and taken as obvious from the context, or their value being deferred to some later time.
It seems that we can define ethics based on information: the good would be to maximize available information in the long run. One's contribution to global information would be the measure of one's behavior.
As a conclusion, we have plenty of well-defined tools that allow to build expressiveness hierarchies among programming languages. These tools seem almost never used in common courses about computer languages, which is a shame, and leads to most available language been very poorly expressive. Unhappily, we quickly see how poorly expressive are available languages relatively to what can be done, and how even among these available languages some are miserably expressive as compared to others.
The simplest idea in garbage collection is to lazily allocate
memory locations where to store for the objects,
which objects in an infinite
abstract space are made available for actual computation only if they are
needed by the (finite) program running. Object representation are allocated
on a heap when needed, and the space used is eventually freed when the object
is not needed anymore, so that unnecessary objects won't fill the (finite,
costly) memory resource. Note that computation for garbage collection can
*sometimes* be done at compile-time,
for objects that do not
If no garbage collection is done, memory may be eventually filled with
unuseful objects as the program runs, and unable to allocate space for new
useful ones. Whereas there would have been enough space should those unuseful
objects' space have been freed. Garbage collection is thus essential for a
persistent system.
The simplest garbage collection scheme is to have a counter for each object.
Each time a new reference to the object is created, the counter is incremented,
while each time an existing reference is destroyed, the counter is decremented.
When the counter is zero, the object space is freed.
There are several ways to eliminate this hole problem.
partially or completely:
This method is simple, but involves a large overhead each time a reference
is created or destroyed (note that a "same" reference may be copied many
times, as long as those copies do not escape, i.e. be destroyed possibly
*after* the original; any escaping copy must be considered a new reference).
The overhead can be largely reduced by compile-time counter managing. Thus, it
is only efficient when new references seldom appear or disappear, but then it
can be very efficient.
This method has a quite nastier drawback: memory used grows and decreases
chaotically, and memory will eventually become like swiss cheese, where there
are holes of free space between used objects. The problem is that while total
free space may be big enough to allocate a new needed object, no contiguous
free space is large enough for the object. This may be prevented if objects
are no larger than some given page size, and no page boundary is ever crossed.
But objects larger than this boundary won't be allocated, or will be on
another heap that'll still potentially have the swiss-cheese problem.
Note that it is possible to achieve hard real-time garbage collection
(whereas manual memory management is unlikely to be real-time),
but you can't have both extra-fast worst response time
and extra-low overall overhead.
Of course, you can again have several pools,
each managed with its own garbage collection mechanism and constraints,
and communicating with other pools in restricted ways.
This makes this method unlikely to work in non-cooperative environment
like usual (crappy) C/C++ software
(written without any way to check compliance to the constraints,
and linked to uncontrollable external libraries that
don't even know about these constraints,
and can't be trusted to comply to them).
Another problem with compacting collectors
is that copying objects to their new location takes time.
Often, you'll want to achieve a "virtual memory" system
(using some hardware support or not, depending on availability
and fitness of available support to the purpose),
whereby though objects look like they are moving,
most of the time only virtual references to them
(basically, indirect pointers) are moving,
with the main data staying quiet at the same "physical" address.
Another thing that takes time in moving collectors
is consistently correcting all the virtual addresses
that point to an object before the old location can actually be freeed.
The worst about it is that it might involve
touching a lot of else unused memory,
incurring misses in the various hardware- and software- managed caches.
That's why even if you might need a moving collector for worst case
swiss cheese scenario,
you'll most likely want a non-moving collector during usual life,
and run the moving collector when your computer
has some free CPU cycles and is not needed for interaction (e.g. at night),
and/or in emergency cases
(when the usual collector is brought down by the swiss cheese syndrom).
As humans can only reach human-reachable things, we can conclude that nothing that is holy thing is in a human's grasp. Conversely, we see that nothing that is in human grasp is holy. Thus, anything we can successfully talk about is not holy, and there's no point trying to talking about holy things.
In traditional OSes, processes are so insecure that the system has to completely, systematically paranoidly isolate processes one from the other. This isolation is like having people put in quarantine to prevent possible diseases to propagate. But it also prevents people from interacting one with the other (i.e. to have any social life), and finally people have to cheat it to live at all, and it then loses its few advantages after having wasted a living.