#
摘要: 對象必須實現Serializable,對象代碼如下:
Java代碼
import java.io.Serializable;
import android.graphics.drawable.Drawable;
...
閱讀全文
這個文檔能給你一個滿意的答復:)
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限制了用戶空間大小的話。
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()
在 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 的垃圾回收時間間隔、甚至主動關閉垃圾回收機制,從而提高運行效率。
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對象緩沖池里.
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持有內存空間.
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!
本文假定讀者使用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
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
|
例如,第三個參數是 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>