[#112457] [Ruby master Feature#19443] Cache `Process.pid` — "byroot (Jean Boussier) via ruby-core" <ruby-core@...>
Issue #19443 has been reported by byroot (Jean Boussier).
16 messages
2023/02/16
[#112584] [Ruby master Feature#19465] [PATCH] reuse open(2) from rb_file_load_ok on POSIX-like system — "normalperson (Eric Wong) via ruby-core" <ruby-core@...>
Issue #19465 has been reported by normalperson (Eric Wong).
9 messages
2023/02/25
[#112595] [Ruby master Feature#19465] [PATCH] reuse open(2) from rb_file_load_ok on POSIX-like system
— "nobu (Nobuyoshi Nakada) via ruby-core" <ruby-core@...>
2023/02/25
SXNzdWUgIzE5NDY1IGhhcyBiZWVuIHVwZGF0ZWQgYnkgbm9idSAoTm9idXlvc2hpIE5ha2FkYSku
[#112613] Re: [Ruby master Feature#19465] [PATCH] reuse open(2) from rb_file_load_ok on POSIX-like system
— Eric Wong via ruby-core <ruby-core@...>
2023/02/26
"nobu (Nobuyoshi Nakada) via ruby-core" <ruby-core@ml.ruby-lang.org> wrote:
[#112615] Re: [Ruby master Feature#19465] [PATCH] reuse open(2) from rb_file_load_ok on POSIX-like system
— SHIBATA Hiroshi via ruby-core <ruby-core@...>
2023/02/27
MzUxMzZlMWU5YzIzMmFkN2EwMzQwN2I5OTJiMmU4NmI2ZGY0M2Y2MyBpcyBicm9rZW4gd2l0aCBg
[#112626] Re: [Ruby master Feature#19465] [PATCH] reuse open(2) from rb_file_load_ok on POSIX-like system
— Eric Wong via ruby-core <ruby-core@...>
2023/02/28
```
[ruby-core:112554] [Ruby master Bug#19460] Class not able to be garbage collected
From:
"byroot (Jean Boussier) via ruby-core" <ruby-core@...>
Date:
2023-02-23 15:50:22 UTC
List:
ruby-core #112554
Issue #19460 has been updated by byroot (Jean Boussier).
I just had a look at this.
Modifying your script a bit to dump the heap:
```ruby
require 'objspace'
class A
def do_something
end
end
a = A.send(:new)
a_id = A.object_id
a = nil
Object.send(:remove_const, :A)
# A should be able to be released now.
10.times { GC.start }
a_ref = ObjectSpace._id2ref(a_id) rescue nil
puts "a_ref: #{a_ref.class}"
# we get NilClass, it is released
ObjectSpace.dump_all(output: File.open("/tmp/foo.json", "w+"))
```
```
$ rg -F '"name":"A"' /tmp/foo.json
17466:{"address":"0x1024f0dc8", "type":"CLASS", "shape_id":13, "slot_size":160, "class":"0x1024f0d28", "variation_count":0, "superclass":"0x1024dfe60", "name":"A", "references":["0x1024dfe60", "0x1022d38b0", "0x10249e988", "0x1022d3798", "0x1022d8dd8"], "memsize":392, "flags":{"wb_protected":true, "old":true, "uncollectible":true, "marked":true}}
```
So the class has slot `0x1024f0dc8`.
Then using `harb`
```
$ ./harb /tmp/foo.json
parsing (100%)
updating references (100%)
generating dominator tree (100%)
harb> rootpath 0x1024f0dc8
root path to 0x1024f0dc8:
ROOT (machine_context)
0x1022d7d98 (IMEMO: env)
0x1024f0dc8 (CLASS: A)
```
It's directly held in the `machine_context`, so I think it's just bad luck because the reference stay in an unused register saved on the stack.
I also modified the script a tiny bit more to see something, and fixed it by accident:
```
require 'objspace'
class A
def do_something
end
end
a = A.send(:new)
a_id = A.object_id
puts ObjectSpace.dump(A)
a = nil
Object.send(:remove_const, :A)
# A should be able to be released now.
10.times { GC.start }
a_ref = ObjectSpace._id2ref(a_id) rescue nil
puts "a_ref: #{a_ref.class}"
# we get NilClass, it is released
```
So yeah, I'm 99% certain you simply hit the issue that the Ruby GC isn't 100% precise. It has to scan the registers and just because a pointer is in a register doesn't mean it's in use.
----------------------------------------
Bug #19460: Class not able to be garbage collected
https://bugs.ruby-lang.org/issues/19460#change-102002
* Author: luke-gru (Luke Gruber)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
I'm working on something where I need to remove a class and release all memory related to that class.
I've stumbled upon a limitation where in some instances I cannot get the class to be GC'd. The problem
(I think) is that inline method caches cache the class, and even if the class would otherwise be gone, it stays.
For example:
```ruby
class A
def do_something
end
end
a = A.send(:new)
a_id = A.object_id
a = nil
Object.send(:remove_const, :A)
# A should be able to be released now.
10.times { GC.start }
a_ref = ObjectSpace._id2ref(a_id) rescue nil
puts "a_ref: #{a_ref.class}"
# we get NilClass, it is released
```
However: using `A.new` above, it can't be GC'd.
If there is an initialize method (even empty) it can't be GC'd.
If there's a method call inside the class to another instance method on self ex: `self.do_something`, it can't be GC'd.
I'm not sure exactly what is going on but it looks like an inline cache marking issue. Maybe caches are getting marked, even inside methods where the method itself doesn't get marked.
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/