-
Notifications
You must be signed in to change notification settings - Fork 211
Open
Description
I think there is a memory leak in haxe's garbage collector, as seen in the example below, the final memory offset must be 0 for the test to pass.
If you define clear_all_allocation
you will see that the test always passes, I think the garbage collector has a leak because the required behavior is that there is no memory allocation.
Only for Linux
Reproduce Code:
package;
import haxe.atomic.AtomicInt;
import sys.thread.FixedThreadPool;
#if linux
@:cppFileCode("
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
")
#end
class AllocationTest {
private static var completedCount:AtomicInt = new AtomicInt(0);
private static var maxThreadCount:Int = 3;
private static var workCount:Int = 100;
private static var threadPool:FixedThreadPool;
public static function main() {
threadPool = new FixedThreadPool(maxThreadCount);
run(true);
}
public static function run(firstRun:Bool):Void {
completedCount = new AtomicInt(0);
var endMemory:Float;
var finalAllocation:Float;
var startMemory:Float;
// Clear garbage to get actual memory usage
#if !clear_all_allocation
cpp.vm.Gc.compact();
#end
startMemory = getMemoryUsage();
for(i in 0...workCount) {
createThread();
}
while (completedCount.load() < workCount) {
Sys.sleep(0.01);
}
if(!firstRun) {
// Clear garbage to get actual memory usage
#if !clear_all_allocation
cpp.vm.Gc.compact();
#end
endMemory = getMemoryUsage();
finalAllocation = endMemory - startMemory;
if(finalAllocation != 0) {
trace("Allocation: " + finalAllocation);
trace("Allocation Test Failed!");
return;
}
trace("Allocation Test Success!");
}
run(false);
}
public static function createThread() {
threadPool.run(() -> {
#if clear_all_allocation
cpp.vm.Gc.compact();
#end
haxe.io.Bytes.alloc(1024 * 50);
completedCount.add(1);
});
}
#if linux
private static function getMemoryUsage():Int
{
untyped __cpp__('FILE *fp;
char line[256];
long memory = 0;
// Open the /proc/self/status file
fp = fopen("/proc/self/status", "r");
if (fp == NULL) {
perror("fopen");
return -1;
}
// Read each line and look for the VmRSS field
while (fgets(line, sizeof(line), fp)) {
if (strncmp(line, "VmRSS:", 6) == 0) {
// VmRSS is in kilobytes, so we convert it to a long
sscanf(line, "VmRSS: %ld kB", &memory);
break;
}
}
fclose(fp);
return memory * 1024;');
return -1;
}
#end
}
Definitions:
-D HXCPP_VERBOSE
-D HXCPP_STACK_LINE
-D HXCPP_STACK_TRACE
-D HXCPP_CHECK_POINTER
-D HXCPP_CPP11
-D HXCPP_GC_MOVING
Metadata
Metadata
Assignees
Labels
No labels