Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we get rid of garbage collection? #4

Closed
yegor256 opened this issue Nov 11, 2016 · 20 comments
Closed

Can we get rid of garbage collection? #4

yegor256 opened this issue Nov 11, 2016 · 20 comments

Comments

@yegor256
Copy link
Member

Can we get rid of garbage collection? Is it technically possible? If all objects are immutable, I think it is...

@akryvtsun
Copy link

As EO(L) will be compiled into Java lang then why garbage collection question was raised at all?

@yegor256
Copy link
Member Author

@Englishman we can compile into Java code with only static methods, no objects. There will be no garbage collection in this case.

@yegor256
Copy link
Member Author

@Englishman and Java won't be the only target platform. we will compile to other platforms too, but later (C, maybe Assembly directly, etc)

@SilasReinagel
Copy link

How would all objects being immutable relate to garbage collection? Aren't objects still being retained in memory until they cease to be needed? Are you proposing developers manually cleanup their objects again?

@gukoff
Copy link
Contributor

gukoff commented Nov 18, 2016

In case all objects are immutable, the garbage collection seems to be unnecessary, because:

  • circular dependencies are impossible;
  • we can use reference counting to determine whether an object has to be destructed;
  • we can consider an empty default destructor and the universal after-destructor behaviour: decrement reference counters of all attributes and free the memory. It would make us to write destructors only when it's really necessary(open descriptors, etc);
  • explicit destruction is better than implicit destruction.

@mdbs99
Copy link
Contributor

mdbs99 commented Nov 18, 2016

@gukoff this is exactly behavior (all you wrote) in Object Pascal — and I liked.

@gukoff
Copy link
Contributor

gukoff commented Nov 19, 2016

@gukoff this is exactly behavior (all you wrote) in Object Pascal — and I liked.

Here, the first statement is the most important. I guess, not all the objects are immutable in Object Pascal; does every circular dependency lead to a memory leak there?

@mdbs99
Copy link
Contributor

mdbs99 commented Nov 19, 2016

@gukoff the objects in Object Pascal are the same that Java: They are mutable by default. Your code will make them immutable.
There are no memory leak because the programmer controls that. Don't exists a CG.
But if you use Interfaces instances, the compiler uses reference counting and release these instances when them get out the scope and no more referenced by anyone.

PS: I have a blog that talks about truly object-oriented programming using Object Pascal.

@stain
Copy link
Contributor

stain commented Nov 21, 2016

If all objects would live on the stack, then there is no need for GC, just reference counting. However then you would want to have tail recursion so you can shorten the stack - tail recursion on the JVM stack is a bit tricky.

@pchmielowski
Copy link
Contributor

BTW. if someone is not familiar with details of Garbage Collection and Reference Counting approaches (like myself until recently), I'm recommending this short podcast:
http://fragmentedpodcast.com/episodes/064/

@alexpanov
Copy link
Contributor

I do not understand the issue. Please correct me if I'm wrong with my assumptions.
As far as I see it, there are three ways to go about garbage collection without having to deal with memory leaks:

  1. Do automatic GC;
  2. Do manual GC;
  3. Do no GC at all and make no new objects.

Option 2 is tedious and error prone. I believe it should be out of the realm of possibility unless there is a goal of not having any adoption at all.

Option 3 is something I'm not certain about. If all objects are immutable, how does HTTP request processing look like, for example? Am I correct when I say that there will be at least some objects created to response to an HTTP request? If it's true, that means that option 3 is not possible.

It might be just a matter of preference, however it seems like leveraging existing GC 'infrastructures' is going to save a lot of effort.

I personally am practically certain that I'm not going to use any language that requires manual GC under any circumstances.

@interstar
Copy link

@gukoff Isn't reference counting a kind of garbage collection?

@gukoff
Copy link
Contributor

gukoff commented Nov 30, 2016

@gukoff Isn't reference counting a kind of garbage collection?

You are right, it is. What I meant is the non-deterministic garbage collection.

@psionski
Copy link

psionski commented Nov 30, 2016

@interstar I think yes - both tracing garbage collection and reference counting are forms of garbage collection. What they probably mean is that they want to avoid tracing GC (e.g. mark-and-sweep).

@gukoff, this is a fascinating idea! However, if you truly want no cycles, you have to forbid anything that might semantically appear "simultaneous", for example the bit of Haskell code in https://wiki.haskell.org/Tying_the_Knot :

cyclic = let x = 0 : y
             y = 1 : x
         in  x

Note that even though no mutable values were used, there's still a cycle.

Does this make sense? Or is this irrelevant given the rest of the language?

@moriline
Copy link

moriline commented Dec 2, 2016

with all due respect you should will be set muttable objects(Sooner or later), because some objects have different states.

@stain stain mentioned this issue Dec 2, 2016
@Lewiscowles1986
Copy link

Surely this would be unworkable (working against the platform) as the JVM platform implements it's own GC? (so you'll be GC'd anyway)

@zeitlinger
Copy link

@gukoff: you can have circular dependencies with reference counting, as long as one is the owner - see https://doc.rust-lang.org/book/ownership.html

@gsnoff
Copy link

gsnoff commented Jan 27, 2019

Speaking of Rust, we could employ a similar borrow checking model with lifetimes.

I.e. have three primitive access modes:

  • Owned (the object is accessible to the scope within which it exists, can be moved to another scope with transfer of the ownership making it inaccessible to the original scope; can also be cloned if the type supports it)
  • Borrowed (an unique reference to the object is created, as long as it exists the object is only accessible through this reference; a stack of such references is possible, with only the topmost being usable)
  • Shared (one or more shared references are created, as long as at least one of them exists the object is only accessible through either of them; shared references can be stacked as well over an existing reference, but unique references can’t be created further)

Obviously the references must not outlive the owned object or underlying stack, hence we’ll need some sort of lifetime tracking for this. More complex references (including automatic reference counting and garbage collection when necessary) can be implemented through trait/aspect contracts which allow automatic conversion to one of the primitive reference types.

Not sure if it makes sense to use references for cloneable types, since clones have the same identity anyway. As an alternative, we could provide aspect contracts which determine whether the type supports copying instead of moving, or creating temporary Views with lifetime guards, and whether the moving/copying of the type and/or its Views can occur across concurrent jobs.

An owned object moved to a method can be consumed (disposed of) by it, becoming no longer accessible. If the method returns a new object implementing the same contract(s), the compiler can basically translate that to a machine code operation over mutable memory, eliminating the overhead for us.

If we really need a “writable memory” object (i.e. for low level state tracking), we can use one of the Cell types for that. Writes to a safe Cell by shared references (or Views) must be gated behind a mutex/spinlock mechanism, failable nonblocking attempts and/or exceptions. Cloneable cells can be implemented as copy-on-write.

See also https://www.reddit.com/r/rust/comments/25ma77/an_alternative_take_on_memory_safety/

@Sammers21
Copy link

Sammers21 commented Mar 10, 2020

@gukoff,

we can use reference counting

Reference counting is a garbage collection technique

determine whether an object has to be destructed

If you compile EO code into java source code files there it would be no way to destruct an object.

explicit destruction is better than implicit destruction.

it is not objective

@yegor256
Copy link
Member Author

This is outside of EO scope, I believe. The destination platform (JVM or such) will deal with objects the way they want.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests