我想知道BinaryFormatter的序列化格式是什么.我发现这个网站提供了一些很好的信息,但它是通过逆向工程获得的,并不完整.
我在哪里可以找到BinaryFormatter序列化格式的官方规范?
我认为64位进程的最大用户空间是8TB,但我做了一点测试,我可以得到的最大值是10-11GB.
注意:我在一个过程中不需要那么多内存,我只是想了解为什么出于好奇.
这是我的测试程序:
static void Main(string[] args)
{
List<byte[]> list = new List<byte[]>();
while (true)
{
Console.WriteLine("Press any key to allocate 1 more GB");
Console.ReadKey(true);
list.Add(new byte[1024 * 1024 * 1024]);
Console.WriteLine("Memory size:");
double memoryUsage = Process.GetCurrentProcess().PeakVirtualMemorySize64 / (double)(1024 * 1024 * 1024);
Console.WriteLine(memoryUsage.ToString("0.00") + " GB");
Console.WriteLine();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
将测试程序更新为更具确定性.
要接受答案,我想知道如果8TB仅是理论上,如何计算实际最大分配内存.
正如这个问题所示: 使用扩展方法提升C#事件 - 这很糟糕吗?
我正在考虑使用此扩展方法来安全地引发事件:
public static void SafeRaise(this EventHandler handler, object sender, EventArgs e)
{
if (handler != null)
handler(sender, e);
}
Run Code Online (Sandbox Code Playgroud)
但是Mike Rosenblum在Jon Skeet的回答中提出了这个问题:
你们需要将[MethodImpl(MethodImplOptions.NoInlining)]属性添加到这些扩展方法中,否则你可以通过JITter优化将代理复制到临时变量的尝试,从而允许空引用异常.
我在发布模式下做了一些测试,看看当扩展方法没有用NoInlining标记时是否可以获得竞争条件:
int n;
EventHandler myListener = (sender, e) => { n = 1; };
EventHandler myEvent = null;
Thread t1 = new Thread(() =>
{
while (true)
{
//This could cause a NullReferenceException
//In fact it will only cause an exception in:
// debug x86, debug x64 and release x86
//why doesn't it …Run Code Online (Sandbox Code Playgroud) 围绕这个进行了很多讨论,每个人都倾向于同意你应该总是调用Delegate.EndInvoke来防止内存泄漏(甚至Jon Skeet说过它!).
我总是毫不疑问地遵循这个准则,但最近我实现了自己的AsyncResult类,并发现可能泄漏的唯一资源是AsyncWaitHandle.
(事实上它并没有真正泄漏,因为WaitHandle使用的本机资源被封装在一个具有Finalizer的SafeHandle中,但它会对垃圾收集器的finalize队列施加压力.即便如此,AsyncResult的良好实现也会只按需初始化AsyncWaitHandle ...)
了解是否存在泄漏的最佳方法就是尝试:
Action a = delegate { };
while (true)
a.BeginInvoke(null, null);
Run Code Online (Sandbox Code Playgroud)
我运行了一段时间,内存保持在9-20 MB之间.
让我们与调用Delegate.EndInvoke时进行比较:
Action a = delegate { };
while (true)
a.BeginInvoke(ar => a.EndInvoke(ar), null);
Run Code Online (Sandbox Code Playgroud)
通过这个测试,内存在9-30 MG之间播放,怪异的呃?(可能是因为当存在AsyncCallback时执行需要更长的时间,因此ThreadPool中将有更多的排队委托)
你觉得怎么样......"神话被破坏了"?
PS ThreadPool.QueueUserWorkItem比Delegate.BeginInvoke效率高一百,它更适合用于fire&forget调用.
我正在构建一个内部开发工具来管理我们的开发环境中常用的不同进程.该工具显示受监视进程的列表,指示其运行状态,并允许启动或停止每个进程.
我想添加从我的工具将调试器附加到受监视进程的功能,而不是在调试 - > 附加到 Visual Studio中的进程并查找进程.
我的目标是让这样的东西Debugger.Launch()显示可用的Visual Studio列表.我无法使用Debugger.Launch(),因为它会在进行调用的进程上启动调试器.我需要类似的东西Debugger.Launch(processId).
我如何实现此功能?
解决方案可能是在每个受监视进程中实现一个命令,以便Debugger.Launch()在从监视工具收到命令时调用,但我更喜欢不需要修改受监视进程代码的东西.
问题:
使用时Debugger.Launch(),未列出已附加调试器的Visual Studio实例.Visual Studio不限于一个附加的调试器,使用Debug → Attach to process时可以在多个进程上附加.
使用Debugger.Launch()或替代时如何绕过此限制?
我最近一直在玩node.js而且我遇到了关于this模块全局范围内使用的奇怪行为.
this 绑定到全局范围中的module.exports:
console.log(this === exports); // -> true
Run Code Online (Sandbox Code Playgroud)
但是this在方法范围内绑定到全局:
(function() { console.log(this === global); })(); // -> true
Run Code Online (Sandbox Code Playgroud)
这也导致了这种令人困惑的行为:
this.Foo = "Weird";
console.log(Foo); // -> throws undefined
(function() { this.Bar = "Weird"; })();
console.log(Bar); // -> "Weird"
Run Code Online (Sandbox Code Playgroud)
我想解决方案是永远不要this在全局范围内使用并明确使用extends或global替代,但是这背后是否存在逻辑,或者它是node.js中的错误或限制?
??? o = new ???();
Console.WriteLine("ToString() -> " + o.ToString() ); //<--- Prints 'ToString() -> '
Console.WriteLine("GetType() -> " + o.GetType()); //<--- NullReferenceException
Run Code Online (Sandbox Code Playgroud)
输出:
ToString() ->
Unhandled Exception: System.NullReferenceException: Object reference not set
to an instance of an object.
at System.Object.GetType()
at Program.Main(String[] args)
Run Code Online (Sandbox Code Playgroud)
什么是类型???以及为什么o.ToString()返回string.Empty并o.GetType()抛出NullReferenceException?
注意:
GetType()未在???类型中重新定义.
我正在处理请求超时机制.我最初的方法是为每个请求创建一个System.Threading.Timer.并发请求的数量可以扩展到数千个.
我想知道我是否应该创建一个TimeoutScheduler,它内部只使用一个计时器而不是每个请求一个.
任何知道System.Threading.Timer内部的人都能给我一些见解,看看TimeoutScheduler是不是一个好主意,或者它是否只会尝试优化已经足够高效的东西.
注意:对于我的场景,计时器精度并不重要.
(我使用System.Threading.Timer对很多并发计时器进行了一些性能测试.它似乎可以很好地扩展,但我不确定它是否会给实际系统带来不必要的压力)
当在x86上运行的算法上尝试调试随机40x性能下降时,我几乎疯了,因为算法大量使用Inter64.CompareExchange和Int64.
我终于隔离了这个问题,只有当所说的Int64不是8字节对齐时才会发生.
无论我如何在StructLayout中显式定位字段,它都依赖于堆上外部对象的基地址.在x86上,基地址将是4字节对齐或8字节对齐.
我想到定义一个12字节的结构并根据对齐将Int64设置为偏移0或偏移4,但这有点像hacky.
c#中有一个很好的做法,用于在x86中对Int64执行互锁操作,以确保正确对齐吗?
编辑
代码可以在这里找到:https: //github.com/akkadotnet/akka.net/pull/1569#discussion-diff-47997213R520
它是一个基于Clr ThreadPool的线程池实现.问题是关于将自定义信号量的状态存储在8字节结构中并使用InterlockedCompareExchange64进行修改.
你有没有看到一个很好的理由来创建自定义二进制休息协议而不是使用基本的http rest实现?
我目前正致力于.Net中面向服务的架构框架,负责托管和使用服务.我不想基于像Remoting或WCF这样的现有框架,因为我需要完全的灵活性和控制来执行自定义优化.
所以在这里我试图找到处理这个SOA框架的最佳协议.我喜欢REST的请求/响应无状态连接性质和用于定义资源的uri,但我不喜欢HTTP的基于文本的性质.
以下是我不喜欢HTTP的论据,如果我错了,请纠正我:
首先是证据,解析文本的效率低于解析二进制文件.我更喜欢包含内容长度和二进制内容的固定长度二进制头.
其次,http请求没有序列号的概念,因此将响应与其请求相关联的唯一方法是用于发送请求和接收响应的套接字连接.这意味着对于指定的套接字一次只能有一个待处理的请求,因此如果服务使用者想要并行向服务发送多个请求,则需要向服务器打开多个套接字.自定义休息协议可以定义请求的序列号,因此请求和响应将与序列号而不是套接字相关联,并且可能在同一套接字上并行发送多个请求.我认为没有办法用HTTP标准地做这个,它可以用基于自定义文本的协议来完成,但为什么不把它做成二进制以获得性能.
为了添加更多上下文,我的SOA框架不需要从非.Net消费者访问,因此我对使用.Net二进制格式化程序或其他自定义二进制格式化程序没有任何限制.
我想要一个自定义二进制休息协议是否有任何意义?如果你认为我错了,请告诉我你的论点.
谢谢.
好奇,我想知道为什么HTTP,按设计,每个插槽只能处理一个待处理请求.
我理解这种限制是因为没有'Id'将请求与其响应相关联,因此将响应与其请求匹配的唯一方法是在发送请求的同一套接字上发送响应.如果套接字上有多个待处理请求,则无法匹配对其请求的响应,因为我们可能无法按照发送请求的相同顺序接收响应.
如果协议设计为对请求和响应具有匹配的"Id",则只有一个套接字可能存在多个挂起请求.这可以大大减少使用Web服务的Internet浏览器和应用程序使用的套接字数量.
HTTP是为了简单而设计的,即使它的效率较低,或者我错过了什么,这是最好的方法吗?
谢谢.
.net ×6
c# ×2
rest ×2
sockets ×2
asynchronous ×1
binary ×1
debugging ×1
http ×1
interlocked ×1
javascript ×1
memory-leaks ×1
node.js ×1
performance ×1
process ×1
soa ×1
timer ×1
x86 ×1