可能重复:
ConcurrentBag中可能的内存泄漏?
EDIT1:
实际的问题是.你能证实这一点,还是我的样本错了,我错过了一些明显的东西?
我认为ConcurrentBag是一个简单的替代无序列表.但是我错了.ConcurrentBag确实将自己作为ThreadLocal添加到创建线程,这基本上会导致内存泄漏.
class Program
{
static void Main(string[] args)
{
var start = GC.GetTotalMemory(true);
new Program().Start(args);
Console.WriteLine("Diff: {0:N0} bytes", GC.GetTotalMemory(true) - start);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Thread.Sleep(5000);
}
private void Start(string[] args)
{
for (int i = 0; i < 1000; i++)
{
var bag = new ConcurrentBag<byte>();
bag.Add(1);
byte by;
while (bag.TryTake(out by)) ;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以制作Diff 250 KB或100 GB,具体取决于我添加到包中的数据量.数据和包包都消失了.
当我用Windbg打破这个时,我做了一个!DumpHeap -type Concurrent
....
000007ff00046858 1 24 System.Threading.ThreadLocal`1+GenericHolder`3[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System],[System.Threading.ThreadLocal`1+C0[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System]], mscorlib],[System.Threading.ThreadLocal`1+C0[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System]], mscorlib],[System.Threading.ThreadLocal`1+C0[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], …Run Code Online (Sandbox Code Playgroud) 在我们的一个课程中,我们大量使用SemaphoreSlim.WaitAsync(CancellationToken)和取消它.
在调用WaitAsync之后不久取消挂起的调用时,我似乎遇到了问题SemaphoreSlim.Release()(很快,我的意思是在ThreadPool有机会处理排队的项目之前),它将信号量置于没有进一步锁定的状态被收购.
由于的是否非确定性性质ThreadPool项目的通话之间执行以Release()和Cancel(),下面的例子并不总是表现出的问题,这种情况下,我已经明确表示要忽略运行.
这是我试图证明问题的例子:
void Main()
{
for(var i = 0; i < 100000; ++i)
Task.Run(new Func<Task>(SemaphoreSlimWaitAsyncCancellationBug)).Wait();
}
private static async Task SemaphoreSlimWaitAsyncCancellationBug()
{
// Only allow one thread at a time
using (var semaphore = new SemaphoreSlim(1, 1))
{
// Block any waits
semaphore.Wait();
using(var cts1 = new CancellationTokenSource())
{
var wait2 = semaphore.WaitAsync(cts1.Token);
Debug.Assert(!wait2.IsCompleted, "Should be blocked by the existing wait");
// Release the …Run Code Online (Sandbox Code Playgroud) 此代码在最后一行抛出ArgumentOutOfRangeException
var initAddress = IPAddress.Parse("1.65.128.190");
var ipv6Address = initAddress.MapToIPv6();
Assert.IsTrue(ipv6Address.IsIPv4MappedToIPv6);
var ipv4Address = ipv6Address.MapToIPv4();
Run Code Online (Sandbox Code Playgroud)
谁能解释为什么MapToIPv6()和MapToIPv4()不兼容往返?
编辑:异常源自IP地址构造函数,由MapToIPv4()调用.
此外,当第一行是
var initAddress = IPAddress.Parse("1.65.128.90");
Run Code Online (Sandbox Code Playgroud)
没有例外被抛出
edit2:正如@Luaan转载的那样,我添加了标签[bug-reporting].还添加了[bcl].让我们看看是否有MS人员跟踪这些标签:)
edit3:在Connect https://connect.microsoft.com/VisualStudio/feedback/details/871964上报告
我被这个System.IO.Directory.GetParent方法的一个非常奇怪的行为击中了脸:
string path1 = @"C:\foo\bar";
DirectoryInfo parent1 = Directory.GetParent(path1);
Console.WriteLine (parent1.FullName); // Prints C:\foo, as expected
// Notice the extra backslash. It should still refer to the same location, right ?
string path2 = @"C:\foo\bar\";
DirectoryInfo parent2 = Directory.GetParent(path2);
Console.WriteLine (parent2.FullName); // Prints C:\foo\bar !!!
Run Code Online (Sandbox Code Playgroud)
我认为它是一个错误,但这种方法自1.0以来一直存在,所以我想现在已经检测到了.另一方面,如果它是按照设计的,我想不出对这种设计的合理解释......
你怎么看 ?这是一个错误吗?如果没有,你如何解释这种行为?
我想有些人可能能够回答这个问题,这是一个出于好奇的问题:
.NET v2中引入的泛型CreateInstance方法System.Activator对泛型参数没有类型约束,但在激活类型上需要默认构造函数,否则MissingMethodException抛出a.对我而言,这个方法似乎应该有类型约束
Activator.CreateInstance<T>() where T : new() {
...
}
Run Code Online (Sandbox Code Playgroud)
只是遗漏或潜伏在这里的一些轶事?
更新
正如所指出的,编译器不允许你编写
private T Create<T>() where T : struct, new()
error CS0451: The 'new()' constraint cannot be used with the 'struct' constraint
Run Code Online (Sandbox Code Playgroud)
但是,请参阅注释可以将结构用作指定new()约束的泛型方法的类型参数.在这种情况下,给定的答案似乎是不限制方法的唯一正当理由......
谢谢你看看这个!
从.NET 4.5(2012)开始,一些新的扩展方法出现在System.Reflection.RuntimeReflectionExtensions类中.然而,新方法似乎没有给我们任何新的东西.一个例子:
static void Main()
{
var prop1 = typeof(string).GetProperty("Length");
var prop2 = typeof(string).GetRuntimeProperty("Length"); // extension, needs: using System.Reflection;
Console.WriteLine(prop1 == prop2);
Action a = Main;
var meth1 = a.Method;
var meth2 = a.GetMethodInfo(); // extension, needs: using System.Reflection;
Console.WriteLine(meth1 == meth2);
}
Run Code Online (Sandbox Code Playgroud)
这写了True两次.
(==操作符在这里超载,但甚至检查参考相等性(object)prop1 == (object)prop2和(object)meth1 == (object)meth2给出True).
那么这些新的公开可见方法的目的是什么?显然,我必须忽略或误解某些东西.
像往常一样,int?意味着System.Nullable<int>(或System.Nullable`1[System.Int32]).
假设你有一个内存IEnumerable<int?>(例如一个List<int?>),让我们称之为seq; 然后你可以找到它的总和:
var seqSum = seq.Sum();
Run Code Online (Sandbox Code Playgroud)
当然这是扩展方法重载int? IEnumerable<int?>.Sum()(文档),它实际上是一个静态方法System.Linq.Enumerable.
但是,该方法永远不会返回null,为什么返回类型声明为Nullable<>?即使在seq空集合或更一般地集合的所有元素都是null类型的值的情况下int?,所讨论的Sum方法仍然返回零,而不是null.
这从文档中可以看出,也可以从System.Core.dll源代码中看出:
public static int? Sum(this IEnumerable<int?> source) {
if (source == null) throw Error.ArgumentNull("source");
int sum = 0;
checked {
foreach (int? v in source) {
if (v != null) sum += v.GetValueOrDefault();
}
}
return sum; …Run Code Online (Sandbox Code Playgroud) 当我BigInteger的大小超过2千兆位(即¼千兆字节;我通过反复试验找到了这个阈值)时,对数方法给出了错误的答案.这个简单的代码说明:
byte[] bb;
bb = new byte[150000001];
bb[150000000] = 1; // sets most significant byte to one
var i1 = new BigInteger(bb);
double log1 = BigInteger.Log(i1);
Console.WriteLine(log1); // OK, writes 831776616.671934
bb = new byte[300000001];
bb[300000000] = 1; // sets most significant byte to one
var i2 = new BigInteger(bb);
double log2 = BigInteger.Log(i2);
Console.WriteLine(log2); // Broken, gives negative number, should be twice 831776616.671934
Run Code Online (Sandbox Code Playgroud)
当然,我们必须有一个数超过正数1,零日志的数量1,而负日志之间的数字0和1(无整数那里).按照惯例,当最高有效字节在和之间时,我的数字i1和i2以上都大1 …
Microsoft.Bcl.Async使开发人员能够使用async/await没有.NET Framework 4.5的关键字,以便他们使用它们.
这很棒,这得益于Microsoft CLR和语言团队中人员的辛勤工作.
现在我很好奇这是如何工作的.
async/await 要求编译器做一些繁重的工作来将代码变成可以等待操作的东西.
编译器最初在.NET Framework 4.0下抛出编译错误,即使它清楚地知道什么async/await意思(Visual Studio 2012/2013.)
那么这个库如何告诉编译器不要抛出与异步操作相关的特定编译错误,并且像在.NET Framework 4.5下一样解除一些代码?
我有一个私有HashSet<string>,它是只读属性的后备字段,它应该返回一个只读集合,以便调用者不能修改集合.所以我试着:
public class MyClass
{
private readonly HashSet<string> _referencedColumns;
public ICollection<string> ReferencedColumns {
get { return new ReadOnlyCollection<string>(_referencedColumns); }
}
Run Code Online (Sandbox Code Playgroud)
这不会编译为ReadOnlyCollection接受a IList<T>未实现的HashSet<T>.还有另一个包装我可以用来拯救我复制这些物品吗?为了我的目的,只需返回实现ICollection<T>(而不是IList<T>)实现的东西即可HashSet<T>.
c# ×8
.net ×7
.net-4.5 ×2
async-await ×2
biginteger ×1
c#-2.0 ×1
clr ×1
ipv4 ×1
ipv6 ×1
linq ×1
logarithm ×1
nullable ×1
reflection ×1
semaphore ×1
sum ×1