- 浏览: 550154 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
hdblocal_:
为什么messageReceived之后,再encode,有点 ...
MINA框架使用总结 -
andey007518:
MINA框架使用总结 -
ymm8505:
我自己的理解 CopyOnWriteArrayList 这个 ...
ArrayList遍历的同时删除 -
spring_springmvc:
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
Eclipse快捷键-方便查找 -
netwelfare:
文章讲解的不够详细,ArrayList在遍历的同时如果去删除或 ...
ArrayList遍历的同时删除
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://canyousee.blogbus.com/logs/3795658.html
最近对程序占用内存方面做了一些优化,取得了不错的效果,总结了一些经验
简要说一下,相信会对大家写出优质的程序有所帮助
下面的论述针对32位系统,对64位系统不适用,后叙
经常你写了一个程序,一测试,功能没问题,一看内存占用也不多,就不去考虑其它的东西
了。但可能程序使用了一个什么数据结构,会当数据规模变大时,内存占用激增。
基本&关键的问题是,Java里各种东东占多少内存?????????
对于primitive类型,有8个
byte short int long float double char boolean 它们的长度分别是
1 2 4 8 4 8 2 1
这个不罗嗦了,举例来说
long[] data=new long[1000];
占用内存 8*1000 bytes
此外,data本身是一个Object,也占用内存若干,后叙,当然它针对 8*1000来说,忽略不
计
再说Object的占用,在说这个之前,先说说引用,一惯的说法是
Java里没有指针了,只有引用,引用是安全的
这个说法没错,但是从机理上来说,引用就是指针,只是jvm对指针的使用检查和限制很多
,这个引用/指针变得很安全
直接来结论:一个引用占4byte ,在32位系统上
Object obj=null; //4byte
Object[] objs=new Object[1000]; //至少4*1000byte
你看我定义了一个 obj,还是null,就占4byte
定义了一个 objs,1000个元素,但都是null啊,就都每个占4byte
是的!!!!!
虽然obj==null,但它已经是 一个引用,或者说一个指针了
指针也要占地方啊!!!!啊!!!!啊!!!!
接下来,直接给另一个结论: Object占8byte,注意,纯Object
Object obj=new Object(); //多少????
8byte?? 错!! 12byte,忘了还有一个引用,8byte是Object的内容
记住 Object obj=new Object(); 占12byte
Object[] objs=new Object[1000];
for(int i=0;i<1000;i++) {
objs[i]=new Object();
}
至少占用 12*1000 bytes
推论: Object占12bytes,似乎和上面的结论矛盾??!!
没有!! 不管Object,没有被垃圾回收之前,总得被别人引用吧?
总的有指针指它吧? 既然指,那个引用or指针就要占地方啊 4byte
加起来是12byte,反正一个Object至少 12bytes
还是直接给结论,推导的过程我就都包办了,咱不是脏活累活抢着干么!!
一个Integer占 16 bytes
这时您可能会有疑问,Integer=Object+int,就是:
public class Integer {
public int value;
}
Integer应该占 8+4=12 bytes啊
你说的有道理,但是jvm对所有的Object有限制!!
这个限制被我发现了,就是不管什么Object占的空间,要是8的倍数
12不是8的倍数,只能是16了!!!
推论:Byte也占16bytes!!!!!!!!!!!
问:
Byte[] bytes=new Byte[1000];
占用空间多少?
答: 约为(至少为) (16+4)*1000 bytes
好家伙!!!!!!!!
论题:数组空间占用怎么算?
我这里直接给结论了,推导这个花了更长的时间:
对于数组来说,数组这个Object有一个length属性,数组的元素相当于其成员
public class Array {
public int length;
//... 其它成员
}
对于数组,我们不是直接可以取length属性么,源于此
public byte[] bytes=new byte[1000];
System.out.println(bytes.length); // 看,有length属性
上面的bytes换算过来是:
public class Array {
public int length;
public byte byte0;
public byte byte1;
...
public byte byte999;
}
上面的bytes占用的内存是:
4+[8+4 + 1*1000] = 4+ [1012]=4+1016=1020
4是 bytes这个引用,8是Object基占的,4是length属性占的
1000是1000个成员占的,本来是 1012,但要求是8的倍数,变成 1016了
总共是 1020
再如:
byte[] bytes=new byte[4];
的内存占用是:
4+[8+4+4*1]=4+[16]=20;
byte[] bytes=new byte[3]; 也是 20
对于元素是Object的数组,Object也是当作其成员,(注意只有引用这个数组的空间,这个
可以推到普通Class上)
Byte[] bytes=new Byte[1000];
这个 bytes的定义相当于:
public class Array {
public int length;
public Byte byte0;
.....
public Byte byte999;
}
占用空间是:
4+[8+4+4*1000]+16*1000= 4+ 4016 + 16000 = 你自己算吧
推论:千万不要用 Byte[] 有20倍的差距!!!!!!!
你可能一下子没明白过来,没关系多琢磨一下,对于普通的class来说
,内容占用就是基加成员的占用,Object成员只记引用
public class Abc {
public int n;
public byte b;
public Object obj;
}
它的内容占用是: [8+4+1+4]=24
所以 Abc one=new Abc()的占用是 4+24=28
提醒:对于 Abc的成员 obj没有计,如果要计入的话,循环这个过程就可以了。(琢磨一下
)
举例:
public class Abc {
public byte b;
public Object obj=null;
}
public class Def {
public int n;
public byte b;
public Abc obj=new Abc();
}
问:
Def one=new Def(); //占多少?
答:
4+[8+4+1+4]+[8+1+4]=4+24+16=44
public class Abc {
public byte b;
public Object obj=null;
}
public class Def {
public int n;
public byte b;
public Abc[] objs=new Abc[100];
{
for(int i=0;i<10;i++) {
objs[i]=new Abc();
}
}
}
问:
Def one=new Def(); //占多少?
答:
kao,一下我也算不出来,不过我写了程序,可以算出来,你给它一个Object,它就能递归
的算出总共占了多少内存,这个程序不复杂,你也可以写出来。我等机会合适了再放出。
单独说一下String,String的结构是:
public class String {
private final char value[];
private final int offset;
private final int count;
private int hash; // Default to 0
}
所以,不考虑那个char[]的占用,一个String最少占用 [8+4+4+4+4]=24bytes
加上引用,共28bytes
所以
String s="";
占用28bytes!!!!! 尽管它的长度为0
如果精确的算,加上引用一个String的占用是
4+24+[8+4+2*length]
String s=""; 的占用是 28+16= 44
String s="ab" 的占用是 28+16= 44
String s="abc" 的占用是 28+24 = 52
要说的是,String是常用的类,这么看,String耗内存很多,所以jvm有优化,同样的内容
尽量重用,所以除了28是必须的外,那个char[] 很可能一样
比方说
String[] s=new String[1000];
for(int i=0;i<1000;i++) {
s[i]=new String("abcdefasdjflksadjflkasdfj");
}
的占用的数量级是 28*1000,那 1000个字符串本身基本上不占内存,只有一份!!!!!
!
反正String 至少是 28,最多也可能是28!!!!!!!!
比较占内存的数据结构,这个很重要:
基本上就是 primitive的包装
实例:
我以前用一个
Hashtable<String,Integer>的结构,有100万个元素
改为String[]+int[]后,内存占用改观不少,速度也很快
100万的String[] 快排一下,也就2秒多,查找用2分,和hash也差不多少
完!
说明:
1。 以上结论适用于32位系统,对于64位系统,有很多不同。反正结论是虽然64位系统能用
的内容更多了,但相同的程序占用内存也多了不少
2。 上面讨论的是类的实例占用的内存,没有考虑静态变量的占用。 静态变量引用的是算
在Class数据里的,内容的占用和实例无关,单独计算就可以了
3。 以上没有考虑 Class本身占的内存。 Class本身也需要占地方啊,就是类的结构,以及
静态变量的引用的占用。但是这个占用是静态的,不随实例变多而变多的。也不好统计出来
,想统计的话,看jvm源码里jclass的表示
4。 别人的劳动成果请尊敬,转载请注明作者zms
评论
改为String[]+int[]后,内存占用改观不少,速度也很快
100万的String[] 快排一下,也就2秒多,查找用2分,和hash也差不多少完!
有点不明白:
hash好象不能排序吧?
要查找的话,数据遍历式的查找怎么会跟地址计算式的差不多?
这个结论有点不可信。
发表评论
-
为何在使用CMS gc算法时会出现连续两次full gc
2011-09-01 11:04 4920现象: jstat -gcutil pid 1000观察到 ... -
配置filter拦截forward之类的内部转发
2011-02-18 17:19 5959在servlet-2.3中,Filter会过滤一切请求,包括服 ... -
request.getRequestURI 与request.getServletPath() 区别
2011-02-16 19:38 7815路径:resin/webapps/my_proj/test/r ... -
ConcurrentHashMap中的remove方法的bug
2010-04-30 11:48 5775最近研究了一下 ConcurrentHashMap中源码发现j ... -
搭建Android开发环境
2010-04-05 23:22 1512在eclipse上安装Android 1.安装eclipse ... -
IoServer源代码阅读笔记
2009-08-23 21:57 2114NIO:写事件要尽量早的被注销. 1,IOServer用一 ... -
一个webapp目录下部署多个web应用
2009-08-21 10:34 2122在同一个resin下的webapp目录部署多个web应用,发现 ... -
java 的深度克隆
2009-07-01 20:07 1743只有实现了cloneable接口才算是真正的深度克隆. 在复 ... -
try finally return
2009-03-20 19:21 1212class Entry { ... -
String和==号的问题
2009-03-09 19:45 1198String name = "you" ... -
Bit数组
2009-01-20 18:56 2857public class BitArray{//用byte数组 ... -
几种通讯协议的比较
2009-01-20 15:26 5319一、综述 本文比较了RMI ... -
java基础知识总结
2009-01-06 00:50 2808http://wiki.caucho.com/Hessian_ ... -
Java基础-关于session的详细解释
2008-12-01 23:49 1312一、术语session 在我的经验里,session这个词 ... -
关于大量缓存对象回收的思考
2008-12-01 15:34 2636前几天面试,被问到了一个问题,如果当前有数亿条记录,但是缓存最 ... -
java 快速排序demo
2008-11-29 19:52 2017快速排序算法思想如下,先选取一个元素作为基准,然后根据这个基准 ... -
java 实现简单的文件拷贝
2008-11-26 17:36 6238昨天面试,面试官要我在黑板上写个java文件复制的代码,但是一 ... -
HashMap的遍历效率讨论
2008-11-26 11:31 3659经常遇到对HashMap中的key和value值对的遍历操作 ... -
Java ArrayList 实现
2008-11-25 23:02 3721ArrayList是List接口的一个可变长数组实现。实现了 ... -
c与java通信时数值类型存储的顺序问题
2008-08-09 15:19 3366Byte:一个字节,标记为byte 0 Word:二个字节,从 ...
相关推荐
灭火机器人设计zms.pdf
ZMS-08:应用媒体处理器.pdf
ZMS-15T型湿式煤电钻维护保养规程.docx
ZliLABS推出首款1080p蓝光品质掌上型应用媒体处理器ZMS-08.pdf
ZiiLABS公司ZMS-08媒体处理器为低功耗设备提供1080p蓝光品质.pdf
ZiiLABS推出全球首款1080p蓝光品质掌上型应用媒体处理器ZMS-08.pdf
ZiiLABS推出全球首款1080p蓝光品质掌上型应用媒体处理器ZMS-08 (2).pdf
ZiiLABS推出全球首款1080p蓝光品质掌上型应用媒体处理器ZMS-08 (1).pdf
微捷码帮助ziiLABS实现双倍性能和减半功耗的100核心ZMS-40处理器.pdf
ZMS 什么是ZMS? ZMS是ZTO Message Service的缩写,使用方与累解分解,屏蔽各消息发生差异,可以将消息进行进行安装,管理,监控,重置管理的平台。 ZMS能做什么? 客户端快速收发 屏蔽消息接收方使用不同类型互换...
In this completely up-to-date volume, Herb Schildt, the world's leading programming author, shows you everything you need to know to develop, compile, debug, and run Java applications and applets....
ZMS表格 ZMS(基于 Zope 的 CMS)的简易配方表格 2015 年 Niels Dettenbach / Syndicat IT & Internet GPLv2 许可 ZMSForms(又名 KForms)允许最终用户兼容处理 HTML 表单、联系表单,包括 ZMS 网站中的表单逻辑。 ...
zMS是一个开放源代码游戏,它将推进RPG游戏。 我们将提供带有某些FPS零件的RPG游戏,并且类型可以随时切换。 您会惊讶于游戏玩法。
ZMS5:在Python 3.7、3.8上运行
本文分析了津巴布韦矿业部门(ZMS)中外国直接投资流入(FDI)的决定因素及其影响,在一项针对2005-14年14种矿物的特殊研究中,估计了随机效应模型。 检查的矿物特定变量包括产能利用率,制造指数量,劳动力成本,...
采用熔融共混和挤出吹膜成型工艺方法,制备低密度聚乙烯(LDPE)/沸石分子筛(ZMS)复合膜。对膜试样的力学性能、结晶性能和透湿性能进行测试。采用DSC方法研究试样的结晶性能并用非等温结晶动力学对其进行分析。结果表明...
jQuery Mobile是一个框架,用于交付具有统一界面的跨平台移动Web应用程序。jQuery Mobile将响应式布局与渐进式增强结合起来,从而通过一个代码库来呈现最佳的用尸体验。
通过压缩 sms 文本内容,这个 midlet (MIDP 2.0) 允许传输超过 160 个字符的文本