C# 在.Net Core 3.1中使用NetFwTypeLib时内存泄漏
我在一直在开发的IDS/IPS流量监视器控制台应用程序中发现了内存泄漏。我以为是实体框架,结果是防火墙代码。下面的代码在.NET4.6.2中工作得非常好,在.NETCore中工作得非常好。但是,它有内存泄漏(特别是第二行C# 在.Net Core 3.1中使用NetFwTypeLib时内存泄漏,c#,.net-core,.net-core-3.1,windows-firewall-api,C#,.net Core,.net Core 3.1,Windows Firewall Api,我在一直在开发的IDS/IPS流量监视器控制台应用程序中发现了内存泄漏。我以为是实体框架,结果是防火墙代码。下面的代码在.NET4.6.2中工作得非常好,在.NETCore中工作得非常好。但是,它有内存泄漏(特别是第二行防火墙规则): 在生产环境中,它只是“按原样”执行这个方法,并且只消耗内存。同样,它是针对.NETCore的,因为我在.NET4.6.1(未注释)中运行了相同的代码一年多,没有出现任何问题 现在,我考虑了一下,并对它进行了注释,我还可以通过一些循环对它进行内部故障排除。这是一场比
防火墙规则):
在生产环境中,它只是“按原样”执行这个方法,并且只消耗内存。同样,它是针对.NETCore的,因为我在.NET4.6.1(未注释)中运行了相同的代码一年多,没有出现任何问题
现在,我考虑了一下,并对它进行了注释,我还可以通过一些循环对它进行内部故障排除。这是一场比赛
它当前运行的服务器是Windows server 2016
更新2:它也可以在Windows 10中复制。下面是复制错误的完整代码的示例:
using System;
using System.Linq;
using NetFwTypeLib;
namespace FirewallLeakTesterCore
{
class Program
{
static void Main(string[] args)
{
int count = 0;
while (count < 1000)
{
Console.WriteLine(count += 1);
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
INetFwRule firewallRule = firewallPolicy.Rules.OfType<INetFwRule>().Where(x => x.Name == "firewallRuleName").FirstOrDefault();
}
Console.ReadKey();
}
}
}
使用系统;
使用System.Linq;
使用NetFwTypeLib;
命名空间FirewallLeakTesterCore
{
班级计划
{
静态void Main(字符串[]参数)
{
整数计数=0;
同时(计数<1000)
{
控制台写入线(计数+=1);
INetFwPolicy2防火墙策略=(INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID(“HNetCfg.FwPolicy2”);
INetFwRule firewallRule=firewallPolicy.Rules.OfType()。其中(x=>x.Name==“firewallRuleName”).FirstOrDefault();
}
Console.ReadKey();
}
}
}
结果如下:
Visual Studio诊断工具:
看起来像微软的bug?我想我会尝试解决其中一个内存分析器,但即使我发现了问题,我能做什么?这是对基本windows库的基本调用,我认为这就是为什么评论中的一些人没有抓住要点的原因
我没有要求任何人对我的应用程序进行内存配置或跟踪问题(从来没有……我已经这样做了)。我在寻求替代方案。是否可能有一个结构或linq问题或其他声明完全可以使用
如果你不想回答这个问题,那就这样吧,但我很难相信没有其他人会碰到这个问题。为什么不使用内存分析器(例如or)来检查你的假设是否正确?你是在让我们猜测我们看不到的应用程序中,在我们不知道的库中,内存泄漏在哪里,PerfView是免费的、独立的,可用于分析堆内存。它值得使用,例如PerfView。不需要太多的学习(只需要几个小时)就可以获得足够的技能,从中获得一些不错的结果,这比避免学习如何使用概要文件所浪费的时间要少得多。我已将我的项目降级为.Net Framework 4.6.1。然而,对于那个些想关注这个问题的人(因为它似乎并没有在谷歌和其他有明显关键词的网站上建立索引):为什么不使用内存分析器(例如or)来检查你们的假设是否正确?你们是在问我们在一个我们看不到的应用程序中,在我们不知道TBTW的库中,内存泄漏在哪里,PerfView是免费的、独立的,可用于分析堆内存。它值得使用,例如PerfView。不需要太多的学习(只需要几个小时)就可以获得足够的技能,从中获得一些不错的结果,这比避免学习如何使用概要文件所浪费的时间要少得多。我已将我的项目降级为.Net Framework 4.6.1。然而,对于那个些想关注这个问题的人(因为它似乎并没有在谷歌和其他有明显关键字的网站上建立索引):
public static void FirewallSetup(string ip, string countryCode, bool isIpsString)
{
// FirewallControl fwCtrl = new FirewallControl();
// fwCtrl.Block(ip, countryCode, isIpsString);
//}
//private void Block(string ip, string countryCode, bool isIpsString)
//{
var remoteAddresses = "*";
string fwRuleName;
bool createNewFwRule = false;
//var fwRuleSuffix = SQLControl.GetFirewallRuleSuffix(countryCode).ToString();
//if (string.IsNullOrEmpty(fwRuleSuffix) || fwRuleSuffix == "0")
//{
fwRuleName = fwRuleNamePrefix + countryCode;
//}
//else
//{
// fwRuleName = fwRuleNamePrefix + countryCode + fwRuleSuffix;
//}
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
INetFwRule firewallRule = firewallPolicy.Rules.OfType<INetFwRule>().Where(x => x.Name == fwRuleName).FirstOrDefault();
//if (firewallRule == null)
//{
// createNewFwRule = true;
//}
//else
//{
// //We need the following for creating the remoteAddresses string below
// //but, also need to count as Windows has a 5000 ip limit per rule
// remoteAddresses = firewallRule.RemoteAddresses;
// string[] aRemoteAddresses = remoteAddresses.Split(",");
// int remoteAddressesCount = aRemoteAddresses.Length;
// //Log.Debug(">>>Firewall remote addresses scope=" + remoteAddresses);
// Log.Warning(">>>" + fwRuleName + " Firewall remote addresses count:" + remoteAddressesCount);
// //5000 would be 0 to 4999 I think?
// if (remoteAddressesCount >= 4999)
// {
// //If remote ip scope is 5000, create a new fw rule
// var newFwRuleNameSuffix = SQLControl.GetNewFirewallRuleSuffix(countryCode).ToString();
// fwRuleName = fwRuleNamePrefix + countryCode + newFwRuleNameSuffix;
// createNewFwRule = true;
// }
//}
//If necessary, we create a new rule
//TODO: Create another method for this?
//if (createNewFwRule)
//{
// firewallRule = (INetFwRule)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
// firewallRule.Name = fwRuleName;
// firewallPolicy.Rules.Add(firewallRule);
// firewallRule.Description = "Block inbound traffic from " + countryCode;
// firewallRule.Profiles = (int)NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_ALL;
// firewallRule.Protocol = (int)NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP;
// firewallRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
// firewallRule.Action = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
// firewallRule.Enabled = true;
// //firewallRule.RemoteAddresses = ip;
// //firewallPolicy.Rules.Add(firewallRule); //throws error and not needed anyway
// //firewallRule.LocalPorts = "4000";
// //firewallRule.Grouping = "@firewallapi.dll,-23255";
// //firewallRule.Profiles = firewallPolicy.CurrentProfileTypes;
//}
//if (isIpsString || remoteAddresses == "*")
//{
// firewallRule.RemoteAddresses = ip;
//}
//else
//{
// firewallRule.RemoteAddresses = remoteAddresses + "," + ip;
//}
}
using System;
using System.Linq;
using NetFwTypeLib;
namespace FirewallLeakTesterCore
{
class Program
{
static void Main(string[] args)
{
int count = 0;
while (count < 1000)
{
Console.WriteLine(count += 1);
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
INetFwRule firewallRule = firewallPolicy.Rules.OfType<INetFwRule>().Where(x => x.Name == "firewallRuleName").FirstOrDefault();
}
Console.ReadKey();
}
}
}