算法练习(66): Java对象的内存占用(1.4.13)

本系列博客习题来自《算法(第四版)》,算是本人的读书笔记,如果有人在读这本书的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(算法交流),想要加入的,请添加我的微信号:zhujinhui207407 谢谢。另外,本人的个人博客 http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

算法(第4版)

知识点

  • Java中int、double、等基本类型的内存占用
  • Java中对象的内存占用
  • Java中数组的内存占用
  • Java中字符串的内存占用

题目

1.4.13 根据正文中的假设分别给出表示以下数据类型的一个对象所需的内存量


1.4.13 Using the assumptions developed in the text, give the amount of memory needed to represent an object of each of the following types:

a.Accumulator
b.Transaction
c.FixedCapacityStackOfStrings with capacity C and N entries 
d.Point2D
e.Interval1D
f. Interval2D 
g. Double

分析

书中关于基本类型的内存占用是这么说的:

For example, since the Java int data type is the set of integer values between 2,147,483,648 and 2,147,483,647, a grand total of 232 different values, typical Java implementations use 32 bits
to represent int values. Similar considerations hold for other primitive types: typical Java implementations use 8-bit bytes, representing each char value with 2 bytes (16 bits), each int value with 4 bytes (32 bits), each double and each long value with 8 bytes (64 bits), and each boolean value with 1 byte (since computers typically access memory one byte at a time).


以上是讲基本类型的内存占用,下面讲地址引用的内存占用(就是指针对象)

For consistency, we assume that 8 bytes are needed to represent addresses, as is typical for 64-bit architectures that are now widely used, recognizing that many older machines use a 32-bit architecture that would involve just 4 bytes per machine address.

接下来是对象的内存占用

To determine the memory usage of an object, we add the amount of memory used by each instance variable to the overhead associated with each object, typically 16 bytes. The overhead includes a reference to the object’s class, garbage collection information, and synchronization information. Moreover, the memory usage is typically padded to be a multiple of 8 bytes (machine words, on a 64-bit machine). For example, an Integer object uses 24 bytes (16 bytes of overhead, 4 bytes for its int instance variable, and 4 bytes of padding).

了解了内存大小计算的原则,下面我们开始一一分析。

这几个类分散在书中的各个地方,让我们先把他们一个一个找出来
a.Accumulator
第一次出现是在92页(中译版是1.2.4.3),他的描述是这样的:

Accumulator. The accumulator API shown on the facing page defines an abstract data type that provides to clients the ability to maintain a running average of data values. For example, we use this data type frequently in this book to process experimental results (see Section 1.4). The implementation is straightforward: it maintains a int instance variable counts the number of data values seen so far and a double instance variable that keeps track of the sum of the values seen so far; to compute the average it divides the sum by the count. Note that the implementation does not save the data values—it could be used for a huge number of them (even on a device that is not capable of holding that many), or a huge number of accumulators could be used on a big system. This performance characteristic is subtle and might be specified in the API, because an implementation that does save the values might cause an application to run out of memory.

public class Accumulator {
    private double total;
    private int N;

    public void addDataValue(double val) {
        N++;
        total += val;
    }

    public double mean() {
        return total / N;
    }

    public String toString() {
        return "Mean (" + N + " values): " + String.format("%7.5f", mean());
    }
}

我们看到首先这个对象Accumulator 要占用16个字节,然后是实例变量total,8个字节,然后N是4个字节,所以一共是16+8+4 = 28,又因为内存的使用一般会被填充为8的倍数(64位计算机中的机器字)。所以需要加4个字节的填充字节,因此是32个字节。

b.Transaction
这个书中只给出了API列表,没有给出具体实现:

好在习题1.2.13需要我们给出实现,我们也在文章算法练习(25):Transaction类设计(1.2.13-1.2.14)中给出了分析。代码如下:

public class Transaction {
    private Date when;
    private String who;
    private double amount;
}

Transaction 类中有Date类,这里我们不用我们写的Date类,而是API中的Date类,有三个属性。

public class Date {
    private final int year;
    private final int month;
    private final int day;
}

Date本身的16字节的开销,再加上有3个int类型,大小是3*4 = 12个字节,再加上4个填充字节,所以Date的对象会占用32个字节。然后我们看String对象的内存占用:

We account for memory in Java’s String objects in the same way as for any other object, except that aliasing is common for strings. The standard String implementation has four instance variables: a reference to a character array (8 bytes) and three int values (4 bytes each). The first int value is an offset into the character ar- ray; the second is a count (the string length). In terms of the instance variable names in the drawing on the facing page, the string that is represented consists of the characters value[offset] through value[offset + count - 1].The third int value in String objects is a hash code that saves recomputation in certain circumstances that need not concern us now. Therefore, each String object uses a total of 40 bytes (16 bytes for object overhead plus 4 bytes for each of the three int instance variables plus 8 bytes for the array reference plus 4 bytes of padding).

由上可知,String对象占用40个字节。综上所述,Transaction占本身的16字节+32字节的Date+40个字节的String+8字节的Double = 96个字节,这里不需要补充字节,因为96是8的倍数。

c.FixedCapacityStackOfStrings
FixedCapacityStackOfStrings是一个我们非常熟悉的类了。在书中133页中有提起,其API表格及实现为:

public class FixedCapacityStackOfStrings
{
   private String[] a; // stack entries
   private int N;      // size
   public FixedCapacityStackOfStrings(int cap)
   {  a = new String[cap];  }
}

我们在习题1.3.1中也有涉及,对应的文章是算法练习(26):Stack概念(1.3.1-1.3.2)大家有兴趣可以温习一下。

d.Point2D
第一次出现在77页,其API为:


书中没有给出实现,文章:算法练习(16):计算两点间距离(1.2.1)给出了实现

public class Point2D {
    public double x;
    public double y;
}

e.Interval1D
第一次出现在77页,其API为:


书中没有给出实现,文章:算法练习(17):相交的间隔对(1.2.2)给出了实现

public class Interval1D {
    public double lo;
    public double hi;
}

f. Interval2D
第一次出现在77页,其API为:


书中没有给出实现,文章:算法练习(18):长方形的一个实现(1.2.3)给出了实现

public class Interval2D {
    public Interval1D x;
    public Interval1D y;    
}

g. Double
Double类型就是基础类型Double类型

答案

a.Accumulator //32字节
b.Transaction //96字节
c.FixedCapacityStackOfStrings with capacity C and N entries //
d.Point2D //
e.Interval1D //
f. Interval2D //
g. Double //

广告

我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335