> ## Documentation Index
> Fetch the complete documentation index at: https://docsuncv2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# getgc

Returns every object (as a table) Roblox is currently holding alive - functions and [userdata](https://www.lua.org/pil/2.7.html) by default, plus one extra type if you provide the `filter` argument.

```luau theme={null}
getgc(filter: string? | includeTables?): function | userdata | table? | string? | thread? | buffer?
```

Pass `true` to also include tables, or pass a type name (`"thread"`, `"string"`, `"buffer"`, or `"table"`) to also include values of that type. With no argument, the list only contains functions and [userdata](https://www.lua.org/pil/2.7.html).

Most commonly used to find functions you cant find via any other method.

## Parameters

The function takes a single optional argument that can be either form below. Pass one or the other - same arg slot, mutually exclusive.

| Parameter       | Type       | Description                                                                                                         |
| --------------- | ---------- | ------------------------------------------------------------------------------------------------------------------- |
| `includeTables` | `boolean?` | `true` adds tables to the result. `false` is equivalent to passing nothing.                                         |
| `filter`        | `string?`  | One of `"thread"`, `"table"`, `"string"`, `"buffer"` - case-sensitive. Adds every value of that type to the result. |

Any other string, and any other arg type, will raise an error.

## Returns

`{function | userdata | thread | table | string | buffer}` - Returns a table containing every live GC object that matches the requested set. The default set is `function`s and `userdata`; the filter argument **adds** to that set (does not replace it).

| Call                              | Returns                        |
| --------------------------------- | ------------------------------ |
| `getgc()` or `getgc(false)`       | functions + userdata           |
| `getgc(true)` or `getgc("table")` | functions + userdata + tables  |
| `getgc("thread")`                 | functions + userdata + threads |
| `getgc("string")`                 | functions + userdata + strings |
| `getgc("buffer")`                 | functions + userdata + buffers |

## Example

In a Roblox game, find the central game-data table by a couple of known keys - useful when no script ever hands you a direct reference to it.

<CodeGroup>
  ```luau Example 1 theme={null}
  <<<<<<< HEAD
  local gc = getgc()
  =======
  -- getgc(filter: string? | includeTables?): function | userdata | table? | string? | thread? | buffer?
  >>>>>>> 50e30f53759b0538759af25c9b271514aa2c9290
  ```

  ```luau Example 2 theme={null}
  for _, t in ipairs(getgc("table")) do
      -- rawget bypasses __index, so a honeypot metatable can't fake these keys
      if rawget(t, "PlayerData") and rawget(t, "GameSettings") then
          print("found game-data table:", t)
          break
      end
  end
  ```
</CodeGroup>

<Tip>
  Anticheats often set up an `__index` honeypot: a table that hands back a value for any key you check, even ones it doesn't really have. Read keys with `rawget` so it can't trick you.

  That vector is most commonly aimed at Dark Dex (and its forks) - the moment Dex references any Instance, the honeypot fires and you get kicked.

  They also may use a weak-table trap: a honeypot object is the only value in a `__mode = "v"` table, with nothing else referencing it. Garbage collection normally removes it from the table.
  If your `getgc` scan still references that object, it will stay => anticheat sees the object having a reference => anticheat kicks you. The check looks something like this:

  ```luau theme={null}
  while true do
      -- weak values: an entry clears once nothing else references its value
      local tracked = setmetatable({
          newproxy(), -- [1] an object a scanner shouldn't touch
          {}, -- [2] another object a scanner shouldn't touch
          {}, -- [3] this is a 'throwaway': once a GC cycle happens, it should also be collected
      }, {__mode = "v"})

      -- make junk until the throwaway is collected, forcing a GC cycle.
      -- this can hang if something references the throwaway,
      -- so in production - it's generally paired with a separate timeout detection.
      while tracked[3] do
          tracked[4] = string.rep("\0\0", 1024)
          tracked[4] = nil
          task.wait()
      end

      -- the GC cycle ran. if both tracked objects were collected, nobody held them
      if not tracked[1] and not tracked[2] then
          continue
      end

      -- a tracked object survived: something is referencing it
      warn("scanner detected") -- or just localplayer:Kick()
  end
  ```

  The entries inside the `tracked` table don't have to be real game objects - a `newproxy()` or `{}` work too.
  So don't keep references to objects from `getgc` - read what you need and don't store them.
</Tip>
