常用链接

统计

最新评论

#

Activitie之间传对象,通过Parcelable(转)

     摘要: 对象必须实现Serializable,对象代码如下: Java代码  import java.io.Serializable;      import android.graphics.drawable.Drawable;     ...  阅读全文

posted @ 2010-09-10 16:00 九宝 阅读(2128) | 评论 (0)编辑 收藏

DU和DF(转)

 
这个文档能给你一个满意的答复:) 
Document Id: 26928Synopsis: du and df Differences (originally published 8/91) 
Update date: 2001-05-13Description: du and df Differences 
-- --- -- ----------- 

This article explains how reporting disk usage du and reporting free disk space 
on file systems df may show different numbers. 

du 
-- 

The du user command gives the number of kilobytes contained in all files and, 
recursively, directories within each specified directory or file (filename). 
If filename is missing, `.' (the current directory) is used.  A file which 
has multiple links to it is only counted once. 

EXAMPLE: 

  system % du 

  5    ./jokes 
  33   ./squash 
  44   ./tech.papers/lpr.document 
  217  ./tech.papers/new.manager 
  401  ./tech.papers 
  144  ./memos 
  80   ./letters 
  388  ./window 
  93   ./messages 
  15   ./useful.news 
  1211 . 

Note that the last number, 1211 is the grand total (in kilobytes) for the 
directory. 

df 
-- 

The df user command displays the following information: 

  amount of disk space occupied by currently mounted file systems 
  the amount of used and available space 
  how much of the file system's total capacity has been used 

Used without arguments, df reports on all mounted file systems. 

EXAMPLE: 

  system % df 

  Filesystem  kbytes  used  avail  capacity  Mounted on 
  /dev/ip0a    7445    4714 1986   70%       / 
  /dev/ip0g   42277   35291 2758   93%       /usr 

Note: used plus avail is less than the amount of space in the file system 
(kilobytes) because the system reserves a fraction of the space in the file 
system to allow its allocation routines to work well.  The amount reserved is 
typically about 10%.  (This may be adjusted using the tunefs command.  Refer to 
the man pages on tunefs(8) for more information.)  When all the space on a file 
system, except for this reserve, is in use, only the super-user can allocate 
new files and data blocks to existing files.  This, however, may cause the file 
system to be over allocated.  When a file system is over allocated in this way, 
df may report that the file system is more than 100% utilized. 

If arguments to df are disk partitions (for example, /dev/ip0as or path names), 
df produces a report on the file system containing the named file.  Thus, df 
shows the amount of space on the file system containing the current directory. 

Problem Definition 
------- ---------- 

This section gives the technical explanation of why du and df sometimes report 
different totals of disk space usage. 

When a program that is running in the background writes to a file while the 
process is running, the file to which this process is writing is deleted. 
Running df and du shows a discrepancy in the amount of disk space usage.  The 
df command shows a higher value. 

Explanation Summary 
----------- ------- 

When you open a file, you get a pointer.  Subsequent writes to this file 
references this file pointer.  The write call does not check to see if the file 
is there or not.  It just writes to the specified number of characters starting 
at a predetermined location.  Regardless of whether the file exist or not, disk 
blocks are used by the write operation. 

The df command reports the number of disk blocks used while du goes through the 
file structure and and reports the number of blocks used by each directory.  As 
far as du is concerned, the file used by the process does not exist, so it does 
not report blocks used by this phantom file.  But df keeps track of disk blocks 
used, and it reports the blocks used by this phantom file.
 du和df命令都被用于获得文件系统大小的信息:df用于报告文件系统的总块数及剩余块数,du -s /<filesystem>用于报告文件系统使用的块数。但是,我们可以发现从df命令算出的文件系统使用块数的值与通过du命令得出的值是不一致的。如下例:
  # du -s /tmp 返回如下值:
  ---12920 /tmp
  而 df /tmp返回如下值:
  Filesystem --512-blocks-- Free --%Used --Iused-- %Iused --Mounted on
  /dev/hd3 --------57344 --42208--- 26% ----391 ------4% --/tmp

  从上面的值我们可以算出<total from df> - <Free from df> = <used block count>: 57344 - 42208 = 15136. 而15136大于12920。该值差异的存在是由于du与df命令实施上的不同: du -s命令通过将指定文件系统中所有的目录、符号链接和文件使用的块数累加得到该文件系统使用的总块数;而df命令通过查看文件系统磁盘块分配图得出总块数与剩余块数。

  文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如i节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,通常称为Meta Data。

  du命令是用户级的程序,它不考虑Meta Data,而df命令则查看文件系统的磁盘分配图并考虑Meta Data。df命令获得真正的文件系统数据,而du命令只查看文件系统的部分情况。例如,一个frag=4096 并且 nbpi=4096的空的大小为4MB的日志文件系统中Meta Data的分配情况如下:

  1 4k block for the LVM

  2 4k super blocks

  2 4k blocks for disk maps

  2 4k blocks for inode maps

  2 4k blocks for .indirect

  32 4k blocks for inodes

  -------------------------

  41 4k blocks for meta data on an empty 4MB file system

  对于AIX 4.X版本:

  执行 du /foo返回的结果如下:

  ----8 -------/foo/lost+found

  ----16 ------/foo

  要使du命令输出的结果与df命令输出的结果匹配,我们必须要加上Meta Data。首先,将41个4k的块转换为以512字节为单位的值:

  41 * 8 = 328

  328(meta data) + 16(from du) = 344

  所以有344个以512字节为单位的块分配给了这个空的文件系统。

  而使用 df /foo命令我们可以得到下面的结果:

  Filesystem --512-blocks --Free --%Used --Iused---%Iused --Mounted on

  /dev/lv01 ------8192 -----7848 -----5% -----16 -----2% ----/foo

  从中我们可以得到该文件系统使用的块数:8192(total blocks) - 7848(free blocks) = 344。该值与上面得出的值一致。

  上面的换算方法对于空的文件系统很容易实现,但是对于非空的文件系统,由于Meta Data中文件间接块的大小不定,因此较难实现。所以我们不需要查看du 与 df返回的值的匹配关系,而只需要了解du -s命令返回的值反映了分配给文件及目录的磁盘块数,而df命令则反映了文件系统的实际分配情况。df命令反映的实际情况包含了用户数据(文件及目录)和Meta Data。

  另一个表现出du与df命令不同之处的例子如下:

  如果用户删除了一个正在运行的应用所打开的某个目录下的文件,则du命令返回的值显示出减去了该文件后的目录的大小。但df命令并不显示减去该文件后的大小。直到该运行的应用关闭了这个打开的文件,df返回的值才显示出减去了该文件后的文件系统的使用情况。

  列出一个目录占用的空间

  1.

  du或du -s或du -k

  du -S | sort -n 可以迅速发现那个目录是最大的。

  2.

  用df可以看到已安装的文件系统的空间大小及剩余空间大小。

  3.

  quota -v查看用户的磁盘空间信息,如果你用quota限制了用户空间大小的话。

posted @ 2010-08-26 16:27 九宝 阅读(141) | 评论 (0)编辑 收藏

How does Python manage memory?(http://docs.python.org/3.1/faq/design.html)

The details of Python memory management depend on the implementation. The standard C implementation of Python uses reference counting to detect inaccessible objects, and another mechanism to collect reference cycles, periodically executing a cycle detection algorithm which looks for inaccessible cycles and deletes the objects involved. The gc module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector’s parameters.

Jython relies on the Java runtime so the JVM’s garbage collector is used. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation.

Sometimes objects get stuck in tracebacks temporarily and hence are not deallocated when you might expect. Clear the tracebacks with:

import sys
sys.exc_clear()
sys.exc_traceback = sys.last_traceback = None

Tracebacks are used for reporting errors, implementing debuggers and related things. They contain a portion of the program state extracted during the handling of an exception (usually the most recent exception).

In the absence of circularities and tracebacks, Python programs need not explicitly manage memory.

Why doesn’t Python use a more traditional garbage collection scheme? For one thing, this is not a C standard feature and hence it’s not portable. (Yes, we know about the Boehm GC library. It has bits of assembler code for most common platforms, not for all of them, and although it is mostly transparent, it isn’t completely transparent; patches are required to get Python to work with it.)

Traditional GC also becomes a problem when Python is embedded into other applications. While in a standalone Python it’s fine to replace the standard malloc() and free() with versions provided by the GC library, an application embedding Python may want to have its own substitute for malloc() and free(), and may not want Python’s. Right now, Python works with anything that implements malloc() and free() properly.

In Jython, the following code (which is fine in CPython) will probably run out of file descriptors long before it runs out of memory:

for file in <very long list of files>:
f = open(file)
c = f.read(1)

Using the current reference counting and destructor scheme, each new assignment to f closes the previous file. Using GC, this is not guaranteed. If you want to write code that will work with any Python implementation, you should explicitly close the file; this will work regardless of GC:

for file in <very long list of files>:
f = open(file)
c = f.read(1)
f.close()

posted @ 2009-11-30 11:01 九宝 阅读(276) | 评论 (0)编辑 收藏

Python 循环引用导致内存泄漏的内存管理TEST ref from:http://meizhini.javaeye.com/blog/249716

  在 Python 中,为了解决内存泄漏问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收。
    因为 Python 有了自动垃圾回收功能,不少初学者就认为自己从此过上了好日子,不必再受内存泄漏的骚扰了。但如果查看一下 Python 文档对 __del__() 函数的描述,就知道好日子里也是有阴云的。下面摘抄一点文档内容:
    Some common situations that may prevent the reference count of an object from going to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object on the stack frame of a function that caught an exception (the traceback stored in sys.exc_traceback keeps the stack frame alive); or a reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in sys.last_traceback keeps the stack frame alive).
    可见,有 __del__() 函数的对象间的循环引用是导致内存泄漏的主凶。特别说明:对没有 __del__() 函数的 Python 对象间的循环引用,是可以被自动垃圾回收掉的。


有 __del__() 函数的对象间的循环引用是导致内存泄漏的主凶。特别说明:对没有 __del__() 函数的 Python 对象间的循环引用,是可以被自动垃圾回收掉的。所以,没什么事,千万不要轻易启用__del__操作。
如何知道一个对象是否内存泄漏了呢?
    方法一、当你认为一个对象应该被销毁时(即引用计数为 0),可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0 来判断是否内存泄漏。如果返回的引用计数不为 0,说明在此刻对象 obj 是不能被垃圾回收器回收掉的。
    方法二、也可以通过 Python 扩展模块 gc 来查看不能回收的对象的详细信息。


    首先,来看一段正常的测试代码:

#--------------- code begin --------------

# -*- coding: utf-8 -*-

import gc
import sys

class CGcLeak(object):
    def __init__(self):
        self._text = '#'*10

    def __del__(self):
        pass

def make_circle_ref():
    _gcleak = CGcLeak()
#   _gcleak._self = _gcleak # test_code_1
    print '_gcleak ref count0:%d' % sys.getrefcount(_gcleak)
    del _gcleak
    try:
        print '_gcleak ref count1:%d' % sys.getrefcount(_gcleak)
    except UnboundLocalError:
        print '_gcleak is invalid!'

def test_gcleak():
    # Enable automatic garbage collection.
    gc.enable()
    # Set the garbage collection debugging flags.
    gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | \
        gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS)

    print 'begin leak test...'
    make_circle_ref()

    print 'begin collect...'
    _unreachable = gc.collect()
    print 'unreachable object num:%d' % _unreachable
    print 'garbage object num:%d' % len(gc.garbage)

if __name__ == '__main__':
    test_gcleak()

#--------------- code end ----------------

    在 test_gcleak() 中,设置垃圾回收器调试标志后,再用 collect() 进行垃圾回收,最后打印出该次垃圾回收发现的不可达的垃圾对象数和整个解释器中的垃圾对象数。

    gc.garbage 是一个 list 对象,列表项是垃圾收集器发现的不可达(即是垃圾对象)、但又不能释放(即不能回收)的对象。文档描述为:A list of objects which the collector found to be unreachable but could not be freed (uncollectable objects).
    通常,gc.garbage 中的对象是引用环中的对象。因为 Python 不知道按照什么样的安全次序来调用环中对象的 __del__() 函数,导致对象始终存活在 gc.garbage 中,造成内存泄漏。如果知道一个安全的次序,那么就打破引用环,再执行 del gc.garbage[:] ,以清空垃圾对象列表。

    上段代码输出为(#后字符串为笔者所加注释):
#-----------------------------------------
begin leak test...
# 变量 _gcleak 的引用计数为 2.
_gcleak ref count0:2
# _gcleak 变为不可达(unreachable)的非法变量.
_gcleak is invalid!
# 开始垃圾回收
begin collect...
# 本次垃圾回收发现的不可达的垃圾对象数为 0.
unreachable object num:0
# 整个解释器中的垃圾对象数为 0.
garbage object num:0
#-----------------------------------------
    可见 _gcleak 对象的引用计数是正确的,也没有任何对象发生内存泄漏。

    如果不注释掉 make_circle_ref() 中的 test_code_1 语句:
    _gcleak._self = _gcleak
也就是让 _gcleak 形成一个自己对自己的循环引用。再运行上述代码,输出结果就变成:
#-----------------------------------------
begin leak test...
_gcleak ref count0:3
_gcleak is invalid!
begin collect...
# 发现可以回收的垃圾对象: 地址为 012AA090,类型为 CGcLeak.
gc: uncollectable <CGcLeak 012AA090>
gc: uncollectable <dict 012AC1E0>
unreachable object num:2
#!! 不能回收的垃圾对象数为 1,导致内存泄漏!
garbage object num:1
#-----------------------------------------
    可见 <CGcLeak 012AA090> 对象发生了内存泄漏!!而多出的 dict 垃圾就是泄漏的 _gcleak 对象的字典,打印出字典信息为:
{'_self': <__main__.CGcLeak object at 0x012AA090>, '_text': '##########'}

    除了对自己的循环引用,多个对象间的循环引用也会导致内存泄漏。简单举例如下:

#--------------- code begin --------------

class CGcLeakA(object):
    def __init__(self):
        self._text = '#'*10

    def __del__(self):
        pass

class CGcLeakB(object):
    def __init__(self):
        self._text = '*'*10

    def __del__(self):
        pass

def make_circle_ref():
    _a = CGcLeakA()
    _b = CGcLeakB()
    _a._b = _b  # test_code_2
    _b._a = _a  # test_code_3
    print 'ref count0:a=%d b=%d' % \
        (sys.getrefcount(_a), sys.getrefcount(_b))
#   _b._a = None    # test_code_4
    del _a
    del _b
    try:
        print 'ref count1:a=%d' % sys.getrefcount(_a)
    except UnboundLocalError:
        print '_a is invalid!'
    try:
        print 'ref count2:b=%d' % sys.getrefcount(_b)
    except UnboundLocalError:
        print '_b is invalid!'

#--------------- code end ----------------

    这次测试后输出结果为:
#-----------------------------------------
begin leak test...
ref count0:a=3 b=3
_a is invalid!
_b is invalid!
begin collect...
gc: uncollectable <CGcLeakA 012AA110>
gc: uncollectable <CGcLeakB 012AA0B0>
gc: uncollectable <dict 012AC1E0>
gc: uncollectable <dict 012AC0C0>
unreachable object num:4
garbage object num:2
#-----------------------------------------
可见 _a,_b 对象都发生了内存泄漏。因为二者是循环引用,垃圾回收器不知道该如何回收,也就是不知道该首先调用那个对象的 __del__() 函数。

    采用以下任一方法,打破环状引用,就可以避免内存泄漏:
[1] 注释掉 make_circle_ref() 中的 test_code_2 语句;
[2] 注释掉 make_circle_ref() 中的 test_code_3 语句;
[3] 取消对 make_circle_ref() 中的 test_code_4 语句的注释。
相应输出结果变为:
#-----------------------------------------
begin leak test...
ref count0:a=2 b=3  # 注:此处输出结果视情况变化.
_a is invalid!
_b is invalid!
begin collect...
unreachable object num:0
garbage object num:0
#-----------------------------------------


    结论:Python 的 gc 有比较强的功能,比如设置 gc.set_debug(gc.DEBUG_LEAK) 就可以进行循环引用导致的内存泄露的检查。如果在开发时进行内存泄露检查;在发布时能够确保不会内存泄露,那么就可以延长 Python 的垃圾回收时间间隔、甚至主动关闭垃圾回收机制,从而提高运行效率。

posted @ 2009-11-30 10:47 九宝 阅读(1315) | 评论 (0)编辑 收藏

Come from : Python源码剖析——Python的内存管理机制

1.小块空间的内存池
在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会
被释放,由于这些内存的申请并不是为了创建对象,所以并没有对象一级的内存池机制。这就
意味着Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间
进行切换,这将严重影响Python的执行效率。为了加速Python的执行效率,Python引入了一
个内存池机制,用于管理对小块内存的申请和释放。这也就是之前提到的Pymalloc机制.

2.在Python2.5中,Python内部默认的小块内存与大块内存的分界点定在256个字节,这个
分界点由前面我们看到的名为SMALL_REQUEST_THRESHOLD的符号控制。也就是说,当申
请的内存小于256字节时,PyObject_Malloc会在内存池中申请内存;当申请的内存大于256
字节时,PyObject_Malloc的行为将蜕化为malloc的行为。当然,通过修改Python源代码,我
们可以改变这个默认值,从而改变Python的默认内存管理行为。

3.在一个对象的引用计数减为0时,与该对象对应的析构函数就会被调用,但是要特别注意的是,调用析构函数并不意味着最终一定会调用free释放内存空间,如果真是这样的话,那频繁地申请、释放内存空间会使 Python的执行效率大打折扣(更何况Python已经多年背负了人们对其执行效率的不满)。一般来说,Python中大量采用了内存对象池的技术,使用这种技术可以避免频繁地申请和释放内存空间。因此在析构时,通常都是将对象占用的空间归还到内存池中。
"这个问题就是:Python的arena从来不释放pool。这个问题为什么会引起类似于内存泄漏的现象呢。考虑这样一种情形,申请10*1024*1024个16字节的小内存,这就意味着必须使用160M的内存,由于Python没有默认将前面提到的限制内存池的WITH_MEMORY_LIMITS编译符号打开,所以Python会完全使用arena来满足你的需求,这都没有问题,关键的问题在于过了一段时间,你将所有这些16字节的内存都释放了,这些内存都回到arena的控制中,似乎没有问题。但是问题恰恰就在这时出现了。因为arena始终不会释放它维护的pool集合,所以这160M的内存始终被Python占用,如果以后程序运行中再也不需要160M如此巨大的内存,
这点内存岂不是就浪费了?"
python内存管理规则:
del的时候,把list的元素释放掉,把管理元素的大对象回收到py对象缓冲池里.

posted @ 2009-11-30 10:35 九宝 阅读(466) | 评论 (0)编辑 收藏

Python 小块空间内存管理TEST ref from: http://www.javaeye.com/topic/309753

mport time

def test():
   for i in range ( 1000000 * 10 ):
        del i

if ( __name__ == "__main__" ):
    test()
    while ( True ):
        time.sleep( 1 )
观察mem:内存维持不变! 

从这点可以猜测:python不是立即释放资源的.

个人测试代码:
-----------------------------------------------test0.py-------------------------------------

import time

def test():
    for i in range ( 1000000 * 10 ):
        del i


def test_2():
    #i = range ( 1000000 * 10 )
    #del i
    pass

def test_3():
    #i = "*" * ( 1000000 * 10 )
    #del i
    pass


if ( __name__ == "__main__" ):
    for i in range( 10 ):
        test()
        test_2()
        test_3()
        time.sleep( 1 )
    while ( True ):
        time.sleep( 1 )
-----------------------------------------------------test0.py-------------------------------------- 

运行 python test0.py

"while ( True ):
        time.sleep( 1 )
 "
保证python不退出.

发现python的内存占用率为60%.

 

如何解决这个问题呢?看下面的:

-----------------------------------------------test1.py-------------------------------------

#coding=utf-8
import time

max_number = 1000000 * 10
def test_0():
    for i in range ( max_number ):
        del i

def test_1():
    for i in range( 1000 ):
        for i in range ( max_number / 1000 ):
            del i

if ( __name__ == "__main__" ):
    #test_0()#内存使用率占40%
    test_1()#内存使用率占0.2%
 
    print "---------------------"
    while ( True ):
        time.sleep( 1 )

-----------------------------------------------test1.py-------------------------------------

 我想问题:问题也许解决了.

这就要看你的实际需求是什么了.

例如:

我做过一个爬虫程序,如果不断往这个线程里面传递url,那么这个线程不到一会就挂了.我的改进方法:就是控制这线程能够接受的url队列长度.以及其他的优化.
 其实这个不是循环导致的内存被python持有,而是range( n )让python分配了很多的内存.退出test(),python回收内存,但是python并不释放了,而是让pool持有内存空间.

posted @ 2009-11-27 16:54 九宝 阅读(456) | 评论 (1)编辑 收藏

void select_font_face (const std::string &family, FontSlant slant, FontWeight weight)

enum Cairo::FontSlant
Enumerator:
FONT_SLANT_NORMAL 
FONT_SLANT_ITALIC 
FONT_SLANT_OBLIQUE 


enum Cairo::FontWeight
Enumerator:
FONT_WEIGHT_NORMAL 
FONT_WEIGHT_BOLD 
0


also:
cr.select_font_face("Droid Sans Bold")  works! Strange!

posted @ 2009-08-12 16:47 九宝 阅读(125) | 评论 (0)编辑 收藏

配置SWT开发环境 -Djava.library.path=.\exe

本文假定读者使用Windows操作系统+JDK 1.4,其他平台和JDK版本应该也是八九不离十。

为了编译和运行SWT程序,我们有两种选择:1- 使用Eclipse SDK;2- 下载单独的SWT二进制文件和源文件。

随Eclipse SDK,我们可以在它的plugins目录下找到SWT的二进制文件,通常的目录名称是:org.eclipse.swt.win32_xxxx,后缀是版本号,在这个目录下有os和ws两个子目录,内容分别是SWT的JNI库和swt.jar。

如果不是使用Eclipse来开发,或者需要SWT的源文件,那么需要下载单独的SWT二进制和源文件包,在下面的地址可以找到:

http://mirror.pacific.net.au/eclipse/eclipse/downloads/drops/R-3.0.1-200409161125/swt-3.0.1-win32.zip


这个zip文件解包以后包含JNI库(一些DLL)和swt.jar,以及swtsrc.zip,这个swtsrc就是我们SWT的源文件了,包括C和Java的源代码。

为了运行SWT程序,我们需要首先编译我们SWT的代码,这个时候需要告诉编译器swt.jar的位置;编译成功以后,我们除了指明classpath包含swt.jar之外,需要在命令行告诉java.exe另一个参数,那就是java.library.path,看上去大概是这个样子:

java -cp %SWT_HOME%\swt.jar SimplestSWT -Djava.library.path=%SWT_HOME%

如果你使用的是Eclipse SDK 3.1M5a或者更新的版本,你可以直接右键.java文件选择Run As -> SWT Application,则不用在命令行写那么长的参数了。

比较有意思的是,我们可以在eclipse.org的SWT下载页面看到目前SWT支持的平台:

       Windows 98/ME/2000/XP
       Windows CE (ARM PocketPC)
       Windows CE (ARM PocketPC, J2ME profile)
       Linux (x86/Motif)
       Linux (x86/GTK 2)
       Linux (AMD 64/GTK 2)
       Solaris 8 (SPARC/Motif)
       QNX (x86/Photon)
       AIX (PPC/Motif)
       HP-UX (HP9000/Motif)      
       Mac OSX (Mac/Carbon)
呵呵,支持的平台虽然有限,不过还是蛮多了。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tiney/archive/2008/09/12/2916785.aspx

posted @ 2009-07-22 16:22 九宝 阅读(953) | 评论 (0)编辑 收藏

java中的sizeof(转)

16位机器,c++,sizeof(int)=2byte长度
32位机器,c++,sizeof(int)=4byte长度
 在C/C++中,当我们想知道一个对象或者一个原始数据类型所占用的内存大小时,只需简单调用sizeof操作符即可,但是,在java中是没有相应的操作符或者方法来直接完成相应功能的。sizeof 在C/C++得到大量的运用,是程序员必不可少的工具之一,那么为什么java却不提供呢?要回答这个问题,我们可以从另外一个角度来看,那就是为什么C/C++中要使用sizeof。C中要使用sizeof主要是因为C程序员要自己管理堆内存的分配和释放,在使用malloc来获取堆内存时,我们必须知道要创建的对象的具体大小,才能根据对象的具体大小从堆中分配相应大小的动态内存,而获取对象大小这个工作就是通过sizeof来完成的。到了C++,我们可以使用操作符new来动态分配内存,这时,对于sizeof的依赖也没有在C时代时那么严重了。在C++中保留sizeof,主要是为了跟C保持兼容。说到这里,我们也可以明白为什么java中为什么没有sizeof了:java中的内存管理任务直接交给了JVM,这比C++更为彻底。同时,java是一个全新设计的完全面向对象语言,不存在C++向下兼容的问题,因此,java中不存在类似sizeof的操作符。(存在即合理,不存在也有它的道理:))。
    但是,有些时候事情并不没有想象中那么简单。当我们用Java编写应用程序时,虽然很多时候我们都不需要了解内存的使用情况,因为JVM已经帮我们照顾好这些珍贵的资源,但是,某些时候,譬如我们要编写一个性能监测工具或者在调试时我们需要知道某个对象所占用的内存大小的。怎么办呢?是不是很怀念我们的sizeof呢。
   不用担心,所谓天无绝人之路。如果我们使用的JDK的版本是5.0或以上,那么,我们可以使用新提供的Instrument包。通过这个包提供的接口和类,我们可以很容易获取一个对象实际占用的内存大小。Instrument的具体描述可以参看JDK文档,【1】提供了一个很好的例子。
   但是,上述方法只能获取对象的占用内存的大小,对于int ,long等原始类型是没有办法得知其内存大小的。有的人可能会问,这些原始类型在java的specification中定义好的吗?我们都知道,int用4个字节,long占用8个字节。对,java规范是对原是类型的大小作出了定义,但是这仅仅是对该类型逻辑上所需的字节作出了规定,具体到每个JVM实现中用到的实际内存大小是没有限制的,我们完全可以实现一个JVM使用8个字节来保存一个int(不知道现在64位CPU机子上是不是使用8个字节(64位)来保存一个int,我这里没有机器可以进行试验)。因此,要知道一个原始类型到底占用多少内存,我们还需另外想办法。【2】【3】【4】【5】提供了相关的信息,有兴趣的朋友可以参考一下。这里,贴出各个基本类型所占用内存的实际大小,看跟你想象中是否一致。(from 【5】Sun JRE 1.4.2 Client Hotspot JVM on Windows)
Type Size (bytes)
java.lang.Object 8
java.lang.Float 16
java.lang.Double 16
java.lang.Integer 16
java.lang.Long 16
java.math.BigInteger 56 (*)
java.lang.BigDecimal 72 (*)
java.lang.String
2*(Length) + 38 ± 2
empty java.util.Vector
80
object reference
4
float array
4*(Length) + 14 ± 2

posted @ 2009-06-24 17:02 九宝 阅读(399) | 评论 (0)编辑 收藏

批处理-如何对作参数的文件名进行操作

 例如,第三个参数是 c:/temp/a.txt
如何取第三个参数的文件路径 c:/temp
SET BIN_DIR=%1                ::取第一个参数
SET RES_DIR=%2                ::取第二个参数
SET TARGET_FILE=%3            ::取第三个参数
SET TARGET_FILE_NAME=%~nx3    ::取第三个参数的文件名
SET TARGET_DIR=%~dp3          ::取第三个参数的路径



如何对作参数的文件名进行操作
?

ECHO %~[<format>]<n>

<format>的取值如下

%~<n>

扩展%<n>,然后去除双引号(" "

%~f<n>

扩展%<n>, 取文件的全路径/文件名/扩展名,纯字符串处理

%~d<n>

扩展%<n>, 取文件的驱动器名

%~p<n>

扩展%<n>, 取文件的路径名

%~n<n>

扩展%<n>, 取文件名,不包括扩展名

%~x<n>

扩展%<n>, 取文件的扩展名

%~s<n>

扩展%<n>, 只包括短文件名的全路径/文件名/扩展名

%~t<n>

扩展%<n>,  文件的最后修改时间

%~z<n>

扩展%<n>, 文件的大小

%~a<n>

扩展%<n>, 文件的属性

%~$<var>:<n>

<var>一般是环境变量PATH, 从中寻找第一个匹配的文件名是%1的文件的全路径,如果找不到则展开为空

             

              以上参数可以组合,其格式是:

%~[{f|d|a|z|s|n|x|t|p}][$<var>:]<n>

posted @ 2009-06-01 16:01 九宝 阅读(688) | 评论 (0)编辑 收藏

仅列出标题
共9页: 上一页 1 2 3 4 5 6 7 8 9 下一页