我试图了解Delphi服务器应用程序中的内存问题:最初我怀疑彻底泄漏,但是现在相信,由于编译器在使用+动态连接字符串时使用了隐藏的临时文件,因此内存的闲置时间比应有的更长。 ,造成痛苦的自由空间内存碎片。
这是Windows上的一整套32位服务器应用程序,Delphi版本已经很老了,我认为它是7,但可以肯定是Unicode之前的版本,并使用Nexus 3内存管理器在其中编写了DLL来挂接所有分配/ free调用(以及GB的内存跟踪)。
我有应用程序源代码,但没有编译器;我不是该应用程序的开发人员(甚至不是Delphi开发人员),但创建了广泛的自定义工具来监视,跟踪和分析内存。我一直在IDA Pro反汇编程序中选择.EXE。
我试图将这种情况减少到最低限度。此代码无意于编译:
procedure TaskThread.RunWorkLoop
begin
while not Terminated do
begin
tsk := WaitForWorkToDo(); // this could sit for minutes at a time
SetThreadName('Working on ' + tsk.Name);
tsk.Run(); // THIS COULD TAKE A LONG TIME
SetThreadName('Idle');
end
end;
Run Code Online (Sandbox Code Playgroud)
SetThreadName() 接受一个const字符串参数并将其挂起,以便系统的其他部分知道此线程在做什么。
我对代码的反汇编显示,编译器已分配了一个隐藏的本地临时变量,以接收“工作中”部分和任务名称部分的串联,这是传递给的SetThreadName地方,它还保留了字符串的句柄。
当任务正在运行时-可能是20分钟-我相信该字符串有两个句柄。一个保存在内部SetThreadName,另一个保存在隐藏的临时文件中。
一切都很好。
然后,当任务结束且线程名称设置为时'Idle',SetThreadName()释放原始字符串并分配文字Idle。
但是:我相信隐藏的本地临时文件仍然保留该字符串的句柄,且refcount = 1,因此它将占用空间,直到过程返回或下一循环来覆盖该隐藏的本地临时文件,释放旧值。
在此期间,程序无法访问它,无法将其显式释放,并且没有用处,但仍在消耗内存。
对于大多数过程而言,这无关紧要,因为它们的开始和结束都相对接近,因此所有内容都可以一次发布,但是在循环服务器应用程序中,这些过程可能会停留更长的时间。这导致我们内存碎片。
在实际的应用程序中,它更像是:
SetThreadName(tsk.Name + '-' + FormatDateTime('mm/dd/yy hh:nn:ss', Now)); …Run Code Online (Sandbox Code Playgroud) 我正在编写一个 .Net Core Windows 服务,这里是一段代码:
internal static class Program
{
public static async Task Main(string[] args)
{
var isService = !(Debugger.IsAttached || args.Contains("--console"));
var builder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<IntegrationService>();
});
if (isService)
{
await builder.RunAsServiceAsync();
}
else
{
await builder.RunConsoleAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想将一些参数传递给我的服务,即IntegrationService- 如何将参数发送到我的服务?
我正在使用优秀的 CsvHelper 库(当前为 v12.2.2)来生成 CSV 文件,并且我正在尝试添加自己的自定义属性以直接在类中指定特殊格式。
我正在编写的记录如下所示(尽管集成需要约 200 个数字字段):
class PayrollRecord {
public int EmployeeID { get; set; }
public decimal RegularPay { get; set; }
public decimal RegularHours { get; set; }
public decimal RegularRate { get; set; }
public decimal OvertimePay { get; set; }
public decimal OvertimeHours { get; set; }
public decimal OvertimeRate { get; set; }
// many many more
}
Run Code Online (Sandbox Code Playgroud)
我需要确保“工资”为小数点后两位,“小时”为 3 位,工资率为 4 位;集成需要这个。
我创建了一个十进制转换器,并将其附加到类映射中:
using CsvHelper;
using CsvHelper.TypeConversion;
// convert decimal …Run Code Online (Sandbox Code Playgroud) 我正在尝试同步并使一些线程/进程为项目进行通信,并且理想情况下我希望访问它们之间的一些共享内存块,而不会让它们与其他进程/资源发生冲突。
我知道 IPC_PRIVATE 在调用shmget()创建它时会生成一个唯一的密钥,但是如果我随后需要该密钥在其他进程中的某个位置打开该区域,我如何访问该生成的key_t值以便将其发送到其他进程?
我目前正在通过 IPC 消息队列发送数据,因此我可以发送 shmid 值,但据我所知,这不起作用,因为 shmid 值对于每个进程都是唯一的。
我没有其他选择,只能尝试ftok()一些随机文件吗?我是否必须为我想要创建的不同共享内存的每个块选择不同的文件?
感谢您的时间。
谁能解释一下这个算法的时间复杂度是多少?
for (i = 1; i <= n; i++){
for(j = 1; j <= n; j += i) { // note: not j++
printf("Iteration %d : %d\n", i, j);
}
}
Run Code Online (Sandbox Code Playgroud) 微控制器负责采样 ADC 值(模数转换)。由于这些部分受容差和噪声的影响,因此可以通过删除 4 个最差值来显着提高精度。查找和删除确实需要时间,这并不理想,因为它会增加循环时间。
想象一下 100MHz 的频率,所以软件的每个命令确实需要 10ns 来处理,命令越多,控制器被阻止执行下一组样本的时间就越长
所以我的目标是尽可能快地完成排序过程,我目前使用这个代码,但这只会删除最糟糕的两个!
uint16_t getValue(void){
adcval[8] = {};
uint16_t min = 16383 //14bit full
uint16_t max = 1; //zero is physically almost impossible!
uint32_t sum = 0; //variable for the summing
for(uint8_t i=0; i<8;i++){
if(adc[i] > max) max = adc[i];
if(adc[i] < min) min = adc[i];
sum=sum+adcval[i];
}
uint16_t result = (sum-max-min)/6; //remove two worst and divide by 6
return result;
}
Run Code Online (Sandbox Code Playgroud)
现在我想扩展这个函数以删除 8 个样本中的 4 个最差值以获得更高的精度。关于如何做到这一点的任何建议?
此外,构建一个高效的函数来查找偏差最大的值,而不是最高和最低值,这将是很棒的。例如,想象这两个数组
uint16_t adc1[8] {5,6,10,11,11,12,20,22};
uint16_t …Run Code Online (Sandbox Code Playgroud) 我有一个 C 程序,可以将测量值输出到标准输出。我用来printf显示它们,格式允许我改变精度
printf("Scan=%d S_0=%.5f S_1=%.5f S_2=%.5f S_3=%.5f", scanId, S0, S1, S2, S3);
Run Code Online (Sandbox Code Playgroud)
我的问题是,我有很多像这样的印刷品,如果我想快速改变精度,我必须对每一份印刷品进行更改。我想知道是否可以使用类似 a 的东西#define将其放在精确的位置,并且它将printf在编译时应用于每个位置。我知道如果不重新编译就不可能轻易实现,但我对此表示同意。我知道与我在 python 中问的类似的东西是:
f"{s_0:.{prec}f}"
Run Code Online (Sandbox Code Playgroud) 我有这个查询,必须选择通过描述过滤的所有书籍,忽略大写/小写。
所以我在 adonis.js / node.js 中进行此查询:
const queryBook = Book
.query()
.with('user')
queryBook.where('description', 'like', '%'+bookDescription[0]+'%')
Run Code Online (Sandbox Code Playgroud)
我有这样的记录bookDescription:
“学生西班牙语版 1 版”
但是当我尝试仅使用小写的“es”进行过滤时,knex 不会返回任何记录。
当我输入“Es”时,将带有我输入的描述的书归还,因此,类似 %es% 不起作用。
我进行了一次调试,发现了这一点:
knex:query select * from "books" where "description" like ? limit ? undefined +7ms
knex:bindings [ '%es%', 10 ] undefined +6ms
Run Code Online (Sandbox Code Playgroud)
显然我没有发现任何错误,但我认为必须like以小写形式返回记录。
我忘记了什么?
GLib库给了我无限的char**篇幅。如何遍历它,打印数组中的每个字符串?
我已经尝试了以下代码,但是即使数组包含多个字符串,它也只会给我第一个字符串。
#include <stdio.h>
#include <glib.h>
static gchar** input_files = NULL;
static const GOptionEntry command_entries[] = {
{"input", 'i', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING_ARRAY, &input_files, "Input files", NULL},
{NULL}
};
int main(int argc, char **argv) {
GOptionContext* option_context;
GError* error;
option_context = g_option_context_new(NULL);
g_option_context_add_main_entries(option_context, command_entries, NULL);
if (!g_option_context_parse(option_context, &argc, &argv, &error)) {
g_printerr("%s: %s\n", argv[0], error->message);
return 1;
}
g_option_context_free(option_context);
if (input_files) {
for (int i = 0; input_files[i]; i++) {
printf("%s", input_files[i]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
$ ./a.out -i One Two …Run Code Online (Sandbox Code Playgroud) 我正在使用TIdHTTP组件执行GET命令,导致出现上述错误消息:
Request.ContentType := 'text/html';
Request.CustomHeader.Values['Authorization'] := 'Basic '+ TIdEncoderMIME.EncodeString(SPIAKey)+':'TIdEncoderMIME.EncodeString(SAPISecret);
Run Code Online (Sandbox Code Playgroud)
TIdSSLIOHHandlerSocket
方法-sslvSSLv2
有人可以帮我解决这个问题吗?