- 浏览: 422060 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (269)
- 原创 (7)
- Java (51)
- Java Concurrency (2)
- IDE (16)
- Linux (46)
- Database (23)
- NoSQL (35)
- Web服务器 (23)
- Log日志 (11)
- HTTP (11)
- HTML (2)
- XML (1)
- Test (7)
- Mina (0)
- Amoeba (4)
- Cobar (1)
- 序列化 (2)
- Python (5)
- PHP (1)
- Socket通信 (1)
- Network (3)
- Struts (2)
- Web前端 (10)
- Maven (6)
- SVN (15)
- Json (1)
- XMPP (2)
- Go (1)
- Other (4)
- 未整理 (5)
最新评论
-
u012374672:
[color=darkred][/color][flash=2 ...
Mongo的ORM框架的学习Morphia(annotations) -
b_l_east:
很有问题啊
利用redis的transaction功能,实现分布式下加锁
版权声明
:转载时请以超链接形式标明文章原始出处和作者信息及本声明
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
发表评论
-
MyBatis-generator使用,为Example添加分页
2017-11-01 16:10 4960数据库为MySQL。1. 在Example类里,加入两个变 ... -
使用Spring MVC统一异常处理实战
2017-08-22 14:26 3361 描述 在J2EE项目的开 ... -
日志组件的关系梳理:如何正确使用它们
2017-08-07 14:25 731背景 由于现在开源框架日益丰富,好多开源框架使用的 ... -
Java中“引用”的几种类型
2017-07-18 17:09 611一. 概述: 强引用(S ... -
Spring和Mybatis整合时无法读取properties的处理方案
2016-11-29 11:39 1741config.properties配置文件信息 ... -
Protobuf使用
2016-07-12 11:49 2191ProtoBuf的官方下载包并不包含jar文件,需要用户自 ... -
jmeter读取外部配置文件
2016-06-06 10:30 0配置文件有两类: 一、路径相关配置文件,只需要了解清楚jm ... -
@SuppressWarnings抑制警告的关键字
2016-05-16 15:45 1963关键字 用途 all to suppress a ... -
Apache的DbUtils框架学习
2016-04-01 19:47 758一、commons-dbutils简介 co ... -
Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
2016-03-30 20:13 705互联网的发展,网站 ... -
Java GC 详解
2016-03-30 19:54 7371、基本回收算法 (1) 引用计数(Reference ... -
JVM(Java虚拟机)优化大全和案例实战
2016-03-30 19:53 500堆内存设置 原理 JVM堆内存分为2块:Perman ... -
Spring事务的传播行为和隔离级别
2016-02-20 22:32 910http://blog.csdn.net/paincupi ... -
java中什么是bridge method(桥接方法)
2016-01-31 19:19 558在看spring-mvc的源码的时候,看到在解析handle ... -
@SuppressWarnings的使用、作用、用法
2016-01-06 16:45 1522在java编译过程中会出现很多警告,有很多是安全的,但是每次 ... -
fastjson遇到的无限递归的问题
2015-09-13 18:09 3983fastjson是用反射的,如果在实体类里 ... -
当spring 容器初始化完成后执行某个方法
2015-08-11 14:56 2262在做web项目开发中,尤其是企业级应用开发的时候,往往会在工 ... -
javac命令初窥
2015-07-30 14:05 1952注:以下红色标记的参数在下文中有所讲解。 用法: ja ... -
JDK各版本地址下载
2015-07-17 13:09 13431. 总地址:http://www.oracle.com/ ... -
jdk1.5-1.9新特性
2015-07-17 13:02 17981.51.自动装箱与拆箱:2.枚举(常用来设计单例模式)3. ...
相关推荐
灭火机器人设计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 个字符的文本