-
Notifications
You must be signed in to change notification settings - Fork 211
Open
Description
Tested on Windows and Linux.
Reproduce Code:
package;
import haxe.atomic.AtomicInt;
import sys.thread.Thread;
import sys.thread.Mutex;
import sys.thread.FixedThreadPool;
#if windows
@:cppFileCode("
#include <windows.h>
#include <psapi.h>
#include <iostream>
using namespace std;
")
#elseif linux
@:cppFileCode("
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
")
#elseif macos
@:cppFileCode("
#include <mach/mach.h>
")
#end
class MemoryTest {
private static var completedCount:AtomicInt = new AtomicInt(0);
private static var maxThreadCount:Int = 10;
private static var activeThreadCount:AtomicInt = new AtomicInt(0);
private static var workCount:Int = 100000;
private static var mutex:Mutex = new Mutex();
#if use_thread_pool
private static var threadPool:FixedThreadPool = new FixedThreadPool(maxThreadCount);
#end
public static function main() {
trace("Hello World!");
cpp.vm.Gc.compact();
cpp.vm.Gc.run(true);
var firstUsage = getMemoryUsage();
trace('Memory usage: ${firstUsage} byte');
//Sys.sleep(10);
while (true) {
if (completedCount.load() >= workCount) {
break;
}
trace('Completed: ${completedCount.load()} / ${workCount}');
// Use mutex to safely check and update thread count
mutex.acquire();
while (activeThreadCount.load() < maxThreadCount) {
activeThreadCount.add(1);
createNewThread();
}
mutex.release();
}
while (activeThreadCount.load() != 0)
{
Sys.sleep(0.01);
}
#if (use_thread_pool && !loop)
threadPool.shutdown();
#end
cpp.vm.Gc.compact();
cpp.vm.Gc.run(true);
var finalUsage = getMemoryUsage();
trace('Memory usage: ${finalUsage} byte');
var diff = finalUsage - firstUsage;
trace('Memory usage diff: ${diff} byte');
// Loop memory test
#if loop
while (true) {
completedCount = new AtomicInt(0);
activeThreadCount = new AtomicInt(0);
Sys.sleep(1);
main();
}
#end
}
private static function createNewThread():Void {
#if use_thread_pool threadPool.run #else Thread.create #end(() -> {
// When you activate it, memory leak is solved (Linux)
#if false
cpp.vm.Gc.compact();
#end
try {
haxe.io.Bytes.alloc(1024 * 50);
} catch (e:Dynamic) {
trace('Thread error: $e');
}
mutex.acquire();
completedCount.add(1);
activeThreadCount.add(-1);
mutex.release();
// When you activate it, "Segmentation fault (core dumped)" occurs, is this a bug? (Linux)
#if false
cpp.vm.Gc.compact();
#end
});
}
#if windows
private static function getMemoryUsage():Float
{
var usage:Float = 0;
untyped __cpp__('
HANDLE hProcess = GetCurrentProcess();
// Bellek kullanım bilgilerini saklayacak değişken
PROCESS_MEMORY_COUNTERS pmc;
// Bellek kullanım bilgilerini alıyoruz
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
{
{0} = pmc.WorkingSetSize;
}
else
{
{0} = 0;
}
CloseHandle(hProcess);
', usage);
return usage;
}
#elseif 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;
}
#elseif macos
private static function getMemoryUsage():Int
{
untyped __cpp__('
task_vm_info_data_t vm_info;
mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
kern_return_t kr = task_info(
mach_task_self(),
TASK_VM_INFO,
(task_info_t)&vm_info,
&count
);
if (kr != KERN_SUCCESS) {
return 1;
}
return (unsigned long long)vm_info.phys_footprint;
');
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
Memory Usage Diff:
Linux: 37650432 byte
Windows: 1314816 byte
Metadata
Metadata
Assignees
Labels
No labels