WeakTable with java gc problem #96

Closed
opened 2021-11-30 01:58:52 +00:00 by maxjiang153 · 1 comment
maxjiang153 commented 2021-11-30 01:58:52 +00:00 (Migrated from github.com)

WeakTable uses java.lang.ref.WeakReference to reference key and value, when java gc occurs, WeakReference data will be released, causing lua data loss.

example code:



import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.WeakTable;

public class Test {

  public static void main(String[] args) {
    LuaTable weakTable = WeakTable.make(false, true);

    for (int i = 0; i < 10000; i++) {
      LuaString key = LuaValue.valueOf("test key" + i);

      weakTable.set(key, WeakTable.make(false, true));
      System.out.println("before gc:");
      System.out.println(weakTable.get(key));  // got table 
      System.gc();
      System.out.println("after gc:");
      System.out.println(weakTable.get(key));   // got null
    }
  }

}

After java gc the WeakSlot key and value will be null. and LuaTable rehash will throw NPE when calc key hash


[0.018s][info][gc] Using G1
before gc:
table: 70dea4e
[0.109s][info][gc] GC(0) Pause Full (System.gc()) 3M->2M(20M) 3.560ms
after gc:
nil
before gc:
table: 5c647e05
[0.111s][info][gc] GC(1) Pause Full (System.gc()) 2M->2M(20M) 1.649ms
after gc:
nil
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.luaj.vm2.LuaValue.type()" because "key" is null
	at org.luaj.vm2.LuaTable.hashSlot(LuaTable.java:509)
	at org.luaj.vm2.WeakTable$WeakValueSlot.keyindex(WeakTable.java:249)
	at org.luaj.vm2.LuaTable.rehash(LuaTable.java:724)
	at org.luaj.vm2.LuaTable.hashset(LuaTable.java:482)
	at org.luaj.vm2.LuaTable.rawset(LuaTable.java:283)
	at org.luaj.vm2.LuaValue.settable(LuaValue.java:3323)
	at org.luaj.vm2.LuaTable.set(LuaTable.java:271)
	at Test.main(Test.java:15)

Is this normal?

WeakTable uses java.lang.ref.WeakReference to reference key and value, when java gc occurs, WeakReference data will be released, causing lua data loss. example code: ``` import org.luaj.vm2.LuaString; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.WeakTable; public class Test { public static void main(String[] args) { LuaTable weakTable = WeakTable.make(false, true); for (int i = 0; i < 10000; i++) { LuaString key = LuaValue.valueOf("test key" + i); weakTable.set(key, WeakTable.make(false, true)); System.out.println("before gc:"); System.out.println(weakTable.get(key)); // got table System.gc(); System.out.println("after gc:"); System.out.println(weakTable.get(key)); // got null } } } ``` After java gc the WeakSlot key and value will be null. and LuaTable rehash will throw NPE when calc key hash ``` [0.018s][info][gc] Using G1 before gc: table: 70dea4e [0.109s][info][gc] GC(0) Pause Full (System.gc()) 3M->2M(20M) 3.560ms after gc: nil before gc: table: 5c647e05 [0.111s][info][gc] GC(1) Pause Full (System.gc()) 2M->2M(20M) 1.649ms after gc: nil Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.luaj.vm2.LuaValue.type()" because "key" is null at org.luaj.vm2.LuaTable.hashSlot(LuaTable.java:509) at org.luaj.vm2.WeakTable$WeakValueSlot.keyindex(WeakTable.java:249) at org.luaj.vm2.LuaTable.rehash(LuaTable.java:724) at org.luaj.vm2.LuaTable.hashset(LuaTable.java:482) at org.luaj.vm2.LuaTable.rawset(LuaTable.java:283) at org.luaj.vm2.LuaValue.settable(LuaValue.java:3323) at org.luaj.vm2.LuaTable.set(LuaTable.java:271) at Test.main(Test.java:15) ``` Is this normal?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: open-autonomous-connection/luaj#96