Issue #12690 has been updated by Yukihiro Matsumoto.

Assignee set to Koichi Sasada

LGTM. Iff Koichi agrees, it should be merged.

Matz.


----------------------------------------
Feature #12690: Improve GC with external library that may use large memory
https://bugs.ruby-lang.org/issues/12690#change-60207

* Author: Kouhei Sutou
* Status: Open
* Priority: Normal
* Assignee: Koichi Sasada
----------------------------------------
GC cares memory allocated by only Ruby. GC doesn't care memory allocated by external library. GC isn't run frequently when external library allocates large memory but Ruby allocates only small memory. In the case, process uses large memory. e.g.: Programs that handle large images may use large memory even when most images are garbage.

How about improving GC to care memory allocated by external library? It means that GC is run when external library allocates large memory.

I created a gem to show the concept: https://github.com/kou/gc-trigger

The gem provides an API that accepts diff of memory usage of external library. Bindings of external library notify diff of memory usage of external library. GC is run when total memory usage of external library overs threshold. Then memory of external library associated with garbage Ruby objects is freed.

I tried the concept with [rcairo](https://github.com/rcairo/rcairo/) that is bindings of [cairo](http://cairographics.org/) 2D graphics library. 

Yellow line is memory usage without the concept and blue line is memory usage with the concept:

![Memory usage with/without the concept](https://raw.githubusercontent.com/kou/gc-trigger/master/sample/cairo-memory.png)

Memory usage is increased without the concept but stable with the concept.

See also: https://github.com/kou/gc-trigger#effect

V8 has an API that is similar to the concept:

https://github.com/v8/v8/blob/5.4.469/include/v8.h#L5937-L5951

> ```c
>  /**
>   * Adjusts the amount of registered external memory. Used to give V8 an
>   * indication of the amount of externally allocated memory that is kept alive
>   * by JavaScript objects. V8 uses this to decide when to perform global
>   * garbage collections. Registering externally allocated memory will trigger
>   * global garbage collections more often than it would otherwise in an attempt
>   * to garbage collect the JavaScript objects that keep the externally
>   * allocated memory alive.
>   *
>   * \param change_in_bytes the change in externally allocated memory that is
>   *   kept alive by JavaScript objects.
>   * \returns the adjusted value.
>   */
>  V8_INLINE int64_t
>      AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes);
> ```




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>