想请教一下各位的战争雷霆占多大的内存小的网游

一个Java对象到底占多大内存? - ImportNew
最近在读《深入理解Java虚拟机》,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存?
在网上搜到了一篇博客讲的非常好:,里面提供的这个类也非常实用:
import java.lang.instrument.I
import java.lang.reflect.A
import java.lang.reflect.F
import java.lang.reflect.M
import java.util.ArrayD
import java.util.D
import java.util.HashS
import java.util.S
* 对象占用字节大小工具类
* @author tianmai.fh
public class SizeOfObject {
public static void premain(String args, Instrumentation instP) {
inst = instP;
* 直接计算当前对象占用空间大小,包括当前类及超类的基本类型实例字段大小、&br&&/br&
* 引用类型实例字段引用大小、实例基本类型数组总占用空间、实例引用类型数组引用本身占用空间大小;&br&&/br&
* 但是不包括超类继承下来的和当前类声明的实例引用字段的对象本身的大小、实例引用数组引用的对象本身的大小 &br&&/br&
* @param obj
public static long sizeOf(Object obj) {
return inst.getObjectSize(obj);
* 递归计算当前对象占用空间总大小,包括当前类和超类的实例字段大小以及实例字段引用对象大小
* @param objP
* @throws IllegalAccessException
public static long fullSizeOf(Object objP) throws IllegalAccessException {
Set&Object& visited = new HashSet&Object&();
Deque&Object& toBeQueue = new ArrayDeque&Object&();
toBeQueue.add(objP);
long size = 0L;
while (toBeQueue.size() & 0) {
Object obj = toBeQueue.poll();
//sizeOf的时候已经计基本类型和引用的长度,包括数组
size += skipObject(visited, obj) ? 0L : sizeOf(obj);
Class&?& tmpObjClass = obj.getClass();
if (tmpObjClass.isArray()) {
//[I , [F 基本类型名字长度是2
if (tmpObjClass.getName().length() & 2) {
for (int i = 0, len = Array.getLength(obj); i & i++) {
Object tmp = Array.get(obj, i);
if (tmp != null) {
//非基本类型需要深度遍历其对象
toBeQueue.add(Array.get(obj, i));
while (tmpObjClass != null) {
Field[] fields = tmpObjClass.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())
//静态不计
|| field.getType().isPrimitive()) {
//基本类型不重复计
field.setAccessible(true);
Object fieldValue = field.get(obj);
if (fieldValue == null) {
toBeQueue.add(fieldValue);
tmpObjClass = tmpObjClass.getSuperclass();
* String.intern的对象不计;计算过的不计,也避免死循环
* @param visited
* @param obj
static boolean skipObject(Set&Object& visited, Object obj) {
if (obj instanceof String && obj == ((String) obj).intern()) {
return visited.contains(obj);
大家可以用这个代码边看边验证,注意的是,运行这个程序需要通过javaagent注入Instrumentation,具体可以看原博客。我今天主要是总结下手动计算Java对象占用字节数的基本规则,做为基本的技能必须get√,希望能帮到和我一样的Java菜鸟。
在介绍之前,简单回顾下,Java对象的内存布局:对象头(Header),实例数据(Instance Data)和对齐填充(Padding),详细的可以看。另外:不同的环境结果可能有差异,我所在的环境是HotSpot虚拟机,64位Windwos。
下面进入正文:
对象头在32位系统上占用8bytes,64位系统上占用16bytes。
原生类型(primitive type)的内存占用如下:
Primitive Type
Memory Required(bytes)
reference类型在32位系统上每个占用4bytes, 在64位系统上每个占用8bytes。
HotSpot的对齐方式为8字节对齐:
(对象头 + 实例数据 + padding) % 8等于0且0 &= padding & 8
对象占用的内存大小收到VM参数UseCompressedOops的影响。
1)对对象头的影响
开启(-XX:+UseCompressedOops)对象头大小为12bytes(64位机器)。
static class A {
A对象占用内存情况:
关闭指针压缩: 16+4=20不是8的倍数,所以+padding/4=24
开启指针压缩: 12+4=16已经是8的倍数了,不需要再padding。
2) 对reference类型的影响
64位机器上reference类型占用8个字节,开启指针压缩后占用4个字节。
static class B2 {
Integer b2b;
B2对象占用内存情况:
关闭指针压缩: 16+4+8=28不是8的倍数,所以+padding/4=32
开启指针压缩: 12+4+4=20不是8的倍数,所以+padding/4=24
64位机器上,数组对象的对象头占用24个字节,启用压缩之后占用16个字节。之所以比普通对象占用内存多是因为需要额外的空间存储数组的长度。
先考虑下new Integer[0]占用的内存大小,长度为0,即是对象头的大小:
未开启压缩:24bytes
开启压缩后:16bytes
接着计算new Integer[1],new Integer[2],new Integer[3]和new Integer[4]就很容易了:
未开启压缩:
开启压缩:
拿new Integer[3]来具体解释下:
未开启压缩:24(对象头)+8*3=48,不需要padding;
开启压缩:16(对象头)+3*4=28,+padding/4=32,其他依次类推。
自定义类的数组也是一样的,比如:
static class B3 {
new B3[3]占用的内存大小:
未开启压缩:48
开启压缩后:32
计算复合对象占用内存的大小其实就是运用上面几条规则,只是麻烦点。
1)对象本身的大小
直接计算当前对象占用空间大小,包括当前类及超类的基本类型实例字段大小、引用类型实例字段引用大小、实例基本类型数组总占用空间、实例引用类型数组引用本身占用空间大小; 但是不包括超类继承下来的和当前类声明的实例引用字段的对象本身的大小、实例引用数组引用的对象本身的大小。
static class B {
static class C {
B[] as = new B[3];
for (int i = 0; i & as. i++) {
as[i] = new B();
未开启压缩:16(对象头)+4(ba)+8(as引用的大小)+padding/4=32
开启压缩:12+4+4+padding/4=24
2)当前对象占用的空间总大小
递归计算当前对象占用空间总大小,包括当前类和超类的实例字段大小以及实例字段引用对象大小。
递归计算复合对象占用的内存的时候需要注意的是:对齐填充是以每个对象为单位进行的,看下面这个图就很容易明白。
现在我们来手动计算下C对象占用的全部内存是多少,主要是三部分构成:C对象本身的大小+数组对象的大小+B对象的大小。
未开启压缩:
(16 + 4 + 8+4(padding)) + (24+ 8*3) +(16+8)*3 = 152bytes
开启压缩:
(12 + 4 + 4 +4(padding)) + (16 + 4*3 +4(数组对象padding)) + (12+8+4(B对象padding))*3= 128bytes
大家有兴趣的可以试试。
实际工作中真正需要手动计算对象大小的场景应该很少,但是个人觉得做为基础知识每个Java开发人员都应该了解,另外:对自己写的代码大概占用多少内存,内存中是怎么布局的应该有一个直觉性的认识。
67 官方建议优先使用synchronized而不是Lock
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:ImportNew.
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2018 ImportNew请完成以下验证码
查看: 8781|回复: 12
电脑小白请教一下单机游戏占用内存吗?
不要使用“如题”,任何软件和游戏都会占用一些内存的。
感谢支持,欢迎常来: )
大型单机如极品飞车、使命召唤,没有2G以上内存打不好,另外对显卡要求也高,一般都是中高端显卡才用的好
个人要求显卡NV GT630以上
其他比如植物大战僵尸,那是毛毛雨了
感谢解答: )
哪个程序都要占内存,只是占用有多有少
恋爱的夏娜
主题内容在卡饭禁止使用“如题”“RT”等字样,请楼主尽快编辑。
话说Windows RT就是这个RT??
这要看你的游戏大小和游戏本身的规模大小,怎么说呢,你总不能指望一个扫雷的内存占用比孤岛危机3还大吧?那么就不科学了。
卡饭实在是有点“奇葩”……
版区有你更精彩: )
本帖最后由 神话哈 于
10:44 编辑
要看单机游戏的需求了,一般来说小型单机游戏的内存占用十分少基本可以忽略不算
如 愤怒的小鸟太空版
无标题.png (99.24 KB, 下载次数: 12)
10:41 上传
相对而言大型的单机游戏需求十分巨大了可以达到1G到2G甚至更多,玩的时候最好关闭其他尽可能关的进程,如果还不行只能考虑加内存条,或开启虚拟内存(开虚拟内存玩大型单机稍微有点伤硬盘)
感谢解答: )
无论是单机游戏还是网络游戏,都需要有画面和声音的支持,所以必定需要内存来进行交换数据的,同时也需要显卡对于画面进行解码,使得画面看上去更逼真。而对于画面及声音的处理的过程中,就会调用CPU及内存来进行处理数据的。所以说,无论是单机游戏还是网络游戏都是需要占用一定比例的内存的!
感谢解答: )
必须要占用,只是大小的区分而已
太模糊了,单机游戏有很多,从扫雷到孤岛危机3,所需的硬件条件各不相同,这个问题很难回答,你不能把你想玩的游戏列出来?
GATX011 发表于
太模糊了,单机游戏有很多,从扫雷到孤岛危机3,所需的硬件条件各不相同,这个问题很难回答,你不能把你想玩 ...
Copyright & KaFan &KaFan.cn All Rights Reserved.
Powered by Discuz! X3.4( 苏ICP备号 ) GMT+8,当前位置 & &
& 内存多大才够用?谈谈内存占用的那些秘密
内存多大才够用?谈谈内存占用的那些秘密
19:39:16&&出处:&&
编辑:快科技 &&)
让小伙伴们也看看:
阅读更多:
好文共享:
文章观点支持
文章价值打分
当前文章打分0 分,共有0人打分
处理 SSI 文件时出错
登录驱动之家
没有帐号?
用合作网站帐户直接登录

我要回帖

更多关于 内存小的网游 的文章

 

随机推荐