开启LOH压缩?
我们知道.NET CLR的GC堆中有一种特殊的堆,它专门存放超过85000byte的对象(详见这里),这就是大对象堆(LOH)。
在.NET Framework 4.5.1之前,微软并没有提供对LOH的压缩操作,这是因为移动大对象的开销是很可观的。不能压缩LOH也会带来一些问题,比如LOH的内存碎片化。不过在.NET Framework 4.5.1种,微软加入了对LOH堆压缩的开关。对于为什么会加入这个开关,个人猜测应该是考虑到计算机性能足以支撑这种操作。具体使用参照以下代码:
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
对于GCLargeObjectHeapCompactionMode.CompactOnce的解释是,在下一次回收gen2时压缩LOH。也就是说这个设置每执行一次只起一次效果,这种设计是很合理的,毕竟如果作为永久开关则会造成不必要的压缩操作。虽然计算机性能足以支持LOH的压缩操作,但这并不意味着不会影响性能。
那么,我怎么知道这个操作达到了预期的效果呢?这就要上调试神器WinDbg了,虽然类似CLRProfiler也可以看出来,但就信息量来说WinDbg要胜一筹。
首先上测试代码:
class Program
{
static void Main(string[] args)
{
//在LOH堆上放一个大对象,调用完后该对象即被认作是垃圾
MakeALohObject(); //在LOH堆上再放一个大对象,此时该对象会被保持
var bytes = new byte[1024*1024]; //注释和取消注释以下开关,并分别dump内存用于分析
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
//触发all gc
GC.Collect(); Console.Read();
} static void MakeALohObject()
{
var obj = new byte[1024 * 1024];
}
}
下面是未打开压缩LOH开关的dump信息节选:
0:000> !eeheap
---------------省略部分信息
Number of GC Heaps: 1
generation 0 starts at 0x000001450b255b90
generation 1 starts at 0x000001450b251018
generation 2 starts at 0x000001450b251000
ephemeral segment allocation context: none
segment begin allocated size
000001450b250000 000001450b251000 000001450b255ba8 0x4ba8(19368)
Large object heap starts at 0x000001451b251000
segment begin allocated size
000001451b250000 000001451b251000 000001451b4599f0 0x2089f0(2132464)
Total Size: Size: 0x20d598 (2151832) bytes.
------------------------------
GC Heap Size: Size: 0x20d598 (2151832) bytes. 0:000> !dumpheap -stat
Statistics:
MT Count TotalSize Class Name
----------------省略部分信息
00007ff8edfa2160 2 706 System.Char[]
00007ff8edfa61a8 2 1072 System.Globalization.CultureData
00007ff8edfa2360 17 1112 System.String[]
00007ff8edfa2f10 26 1456 System.RuntimeType
00007ff8edfa1010 154 6696 System.String
00007ff8edfa1688 5 35144 System.Object[]
00007ff8edfa7248 3 1048904 System.Byte[]
00000145095abf40 24 1051068 Free
Total 294 objects 0:000> !DumpHeap /d -mt 00000145095abf40
Address MT Size
000001450b251000 00000145095abf40 24 Free
000001450b251018 00000145095abf40 24 Free
000001450b251030 00000145095abf40 24 Free
----------------省略部分信息
000001451b259980 00000145095abf40 1048662 Free
从!eeheap命令结果可以看出LOH共2132464byte,约2mb,也就是说虽然回收了一个1mb的byte数组,但是内存并未压缩。从!dumpheap -stat中的Free里面可以找到被释放的1mb空间。
接下来看看打开压缩LOH开关的内存dump:
0:000> !eeheap
----------------省略部分信息
Number of GC Heaps: 1
generation 0 starts at 0x0000015300005390
generation 1 starts at 0x0000015300001018
generation 2 starts at 0x0000015300001000
ephemeral segment allocation context: none
segment begin allocated size
0000015300000000 0000015300001000 00000153000053a8 0x43a8(17320)
Large object heap starts at 0x0000015310001000
segment begin allocated size
0000015310000000 0000015310001000 00000153101099b8 0x1089b8(1083832)
Total Size: Size: 0x10cd60 (1101152) bytes.
------------------------------
GC Heap Size: Size: 0x10cd60 (1101152) bytes. 0:000> !dumpheap -stat
Statistics:
MT Count TotalSize Class Name
----------------省略部分信息
000001536ca7be30 16 414 Free
00007ff8edfa8520 1 432 System.Collections.Generic.Dictionary`2+Entry[[System.Type, mscorlib],[System.Security.Policy.EvidenceTypeDescriptor, mscorlib]][]
00007ff8edfa39d8 6 524 System.Int32[]
00007ff8edfa2160 2 706 System.Char[]
00007ff8edfa61a8 2 1072 System.Globalization.CultureData
00007ff8edfa2360 17 1112 System.String[]
00007ff8edfa2f10 26 1456 System.RuntimeType
00007ff8edfa1010 154 6696 System.String
00007ff8edfa1688 5 35144 System.Object[]
00007ff8edfa7248 3 1048904 System.Byte[]
Total 286 objects
class Program
{
static void Main(string[] args)
{
var cycle = 1000;
var total = 0l;
//预热
MakeGrabage(); for (int j = 0; j < cycle; j++)
{
total += MakeGrabage();
}
Console.WriteLine("平均耗时{0}毫秒", total / (double)cycle);
Console.Read();
} static long MakeGrabage()
{
var objs = new byte[1000][];
//初始化1000个1mb的byte数组
for (int i = 0; i < 1000; i++)
{
objs[i] = new byte[1024 * 1024];
}
//将其中一半置为垃圾对象
for (int i = 0; i < objs.Length; i++)
{
if (i % 2 == 0)
{
objs[i] = null;
}
}
var sw = Stopwatch.StartNew();
//开启或关闭LOH压缩
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
sw.Stop();
var elasped = sw.ElapsedMilliseconds; objs = null;
GC.Collect();
return elasped;
}
}
开启LOH压缩?的更多相关文章
- Nginx 开启gzip 压缩
随着nginx的发展,越来越多的网站使用nginx,因此nginx的优化变得越来越重要,今天我们来看看nginx的gzip压缩到底是怎么压缩的呢? gzip(GNU-ZIP)是一种压缩技术. 经过gz ...
- 【转载】HttpWebRequest开启gzip压缩简介
在用HttpWebRequest对象时,一般我们都没有开启gzip压缩,如果服务端返回的数据比较大,这是我们需要开启gzip压缩,怎么开启呢? 1.给HttpWebRequest对象,添加如下Head ...
- IIS7.5开启GZip压缩
在IIS7.5选择要开启GZip压缩的网站,在功能视图中找到并双击"压缩"图标,在压缩界面中钩选"启用静态内容压缩"和"启用动态内容压缩", ...
- 修改Apache配置文件开启gzip压缩传输
转自:http://down.chinaz.com/server/201202/1645_1.htm 最近无事研究一些Web的优化,用工具page speed检测网站时发现还没有开启gzip压缩,于是 ...
- IIS6.0开启gzip压缩(来自百度)
IIS6.0开启gzip压缩 | 更新:2012-08-10 10:29 1 2 3 4 5 分步阅读 开启gzip可以极大的加速网站.有时压缩比率高达80%,近来测试了一下,最少都有40%以上,还是 ...
- apache 开启zgip 压缩模式
一.Apache开启gzip压缩模式在目录apache\conf\httpd.conf 配置 httpd.conf 文件: #去掉LoadModule deflate_module modules/m ...
- Nginx开启gzip压缩功能
在Nginx安装完成之后,我们可以开启Gzip压缩功能,这里Nginx默认只能对text/html类型的文件进行压缩.下面的指令为开启Gzip的指令: gzip on; gzip_http_versi ...
- WIN2003服务器IIS下如何开启GZIP压缩
在上一篇文章黑客流谈到了关于网页打开速度对SEO的影响,其中提到了网页开启Gzip压缩的好处,接下来我来和大家分享一下WINDOWS系统IIS服务器下如何开启Gzip压缩. 首先我们来了解一下什么是G ...
- apache 配置静态文件缓存和开启gzip压缩
1,设置文件静态缓存3天: 在httpd.conf 里添加如下代码: #文件静态缓存配置 <IfModule expires_module> #打开缓存 ExpiresActive on ...
随机推荐
- Uva 1630 折叠串
题目链接:https://uva.onlinejudge.org/external/16/1630.pdf 题意:折叠串,给一个字符串,相同部分可以折叠,折叠可以嵌套.求最短长度的一种折叠方法.括号和 ...
- ELK初步实践
ELK是一个日志分析和统计框架,是Elasticsearch.Logstash和Kibana三个核心开源组件的首字母缩写,实践中还需要filebeat.redis配合完成日志的搜集. 组件一览 名称 ...
- 复旦高等代数 II(15级)思考题
1.设 $f(x)=x^n+a_{n-1}x^{n-1}+\cdots+a_1x+a_0$ 是整系数首一多项式, 满足: $|a_0|$ 是素数且 $$|a_0|>1+\sum_{i=1}^{n ...
- angular手势事件之on-Hold
.controller( 'actionsheetCtl',['$scope',function($scope){ $scope.onHold=function(){ console.log(even ...
- jdbc.properties各种数据库连接配置
# HSQLDB #jdbc.driverClassName=org.hsqldb.jdbcDriver #jdbc.url=jdbc:hsqldb:hsql://localhost:9001/bo ...
- [bzoj3192][JLOI2013]删除物品(树状数组)
3192: [JLOI2013]删除物品 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 872 Solved: 508[Submit][Status ...
- 用SignalR实现的弹幕功能
弹幕功能通常用于实时显示当前视频或者文档的评论内容,在上快速飞过的方式呈现,看起来比较酷炫. 这种典型的多用户实时交互的功能,很适合使用SignalR实现,通过SignalR提供后台的服务推送功能,客 ...
- svn使用
1 svn地址: svn://www.svn999.com/annie123.test12345 2 svn 账户: 账户使用时期:项目checkout时期 会提示键入用户名密码 3 新增文件 (1) ...
- MySql 创建表 插入数据!
create table stu( id int, sname VARCHAR(20), sex VARCHAR(1), birthday DATETIME) insert into stu valu ...
- 转:Linux内部的时钟处理机制全面剖析
Linux内部的时钟处理机制全面剖析 在 Linux 操作系统中,很多活动都和时间有关,例如:进程调度和网络处理等等.所以说,了解 Linux 操作系统中的时钟处理机制有助于更好地了解 Linux 操 ...