Java中的緊湊堆外結構/組合

在上一篇文章中,我詳細介紹了代碼對主內存的訪問方式的含義。 從那時起,我對使用Java可以做什么以實現更可預測的內存布局有很多疑問。 有些模式可以使用數組支持的結構來應用,我將在另一篇文章中討論。 這篇文章將探討如何模擬Java中非常缺少的功能-與C提供的功能類似的結構數組。

結構在堆棧和堆上都非常有用。 據我所知,不可能在Java堆棧上模擬此功能。 無法在堆棧上執行此操作真是令人遺憾,因為它極大地限制了某些并行算法的性能,但這又是另一回事。

在Java中,所有用戶定義的類型都必須存在于堆中。 在一般情況下,Java堆由垃圾收集器管理,但是Java進程中的堆更大。 通過引入直接ByteBuffer ,可以分配內存,垃圾回收器不會跟蹤該內存,因為本機代碼可將其用于任務,例如避免為IO向內核復制數據或從內核復制數據。 因此,一種管理結構的方法是在ByteBuffer中偽造它們,這是一種合理的方法。 這可以允許緊湊的數據表示,但是具有性能和大小限制。 例如,不可能有一個大于2GB的ByteBuffer,并且所有訪問都經過邊界檢查,這會影響性能。 存在使用Unsafe的替代方法,它不僅速度更快而且不受ByteBuffer的大小限制。

我要詳細介紹的方法不是傳統的Java。 如果您的問題空間正在處理大數據或極高的性能,那么就會有好處。 如果您的數據集很小,并且性能不是問題,那么請立即逃避以避免陷入本機內存管理的黑手黨。

我將詳細介紹的方法的好處是:

  1. 顯著改善的性能
  2. 更緊湊的數據表示
  3. 能夠處理非常大的數據集,同時避免了令人討厭的GC暫停[1]

各種選擇都有其后果。 通過采用下面詳述的方法,您將自己負責一些內存管理。 弄錯了會導致內存泄漏,或者更糟的是,您可能使JVM崩潰! 謹慎行事...

合適的例子– 貿易數據

財務應用程序面臨的一個共同挑戰是捕獲和處理大量的訂單和交易數據。 對于該示例,我將創建一個很大的內存貿易數據表,可以對它運行分析查詢。 該表將使用兩種對比方法構建。 首先,我將采用傳統的Java方法創建大型數組并引用單個Trade對象。 其次,我保持用法代碼相同,但是用可通過Flyweight模式操作的堆外結構數組替換大數組和Trade對象。

如果對于傳統的Java方法,我使用其他一些數據結構(例如Map或Tree),則內存占用量將更大,而性能會更低。

傳統的Java方法

public class TestJavaMemoryLayout
{private static final int NUM_RECORDS = 50 * 1000 * 1000;private static JavaMemoryTrade[] trades;public static void main(final String[] args){for (int i = 0; i < 5; i++){System.gc();perfRun(i);}}private static void perfRun(final int runNum){long start = System.currentTimeMillis();init();System.out.format('Memory %,d total, %,d free\n',Runtime.getRuntime().totalMemory(),Runtime.getRuntime().freeMemory());long buyCost = 0;long sellCost = 0;for (int i = 0; i < NUM_RECORDS; i++){final JavaMemoryTrade trade = get(i);if (trade.getSide() == 'B'){buyCost += (trade.getPrice() * trade.getQuantity());}else{sellCost += (trade.getPrice() * trade.getQuantity());}}long duration = System.currentTimeMillis() - start;System.out.println(runNum + ' - duration ' + duration + 'ms');System.out.println('buyCost = ' + buyCost + ' sellCost = ' + sellCost);}private static JavaMemoryTrade get(final int index){return trades[index];}public static void init(){trades = new JavaMemoryTrade[NUM_RECORDS];final byte[] londonStockExchange = {'X', 'L', 'O', 'N'};final int venueCode = pack(londonStockExchange);final byte[] billiton = {'B', 'H', 'P'};final int instrumentCode = pack( billiton);for (int i = 0; i < NUM_RECORDS; i++){JavaMemoryTrade trade = new JavaMemoryTrade();trades[i] = trade;trade.setTradeId(i);trade.setClientId(1);trade.setVenueCode(venueCode);trade.setInstrumentCode(instrumentCode);trade.setPrice(i);trade.setQuantity(i);trade.setSide((i & 1) == 0 ? 'B' : 'S');}}private static int pack(final byte[] value){int result = 0;switch (value.length){case 4:result = (value[3]);case 3:result |= ((int)value[2] << 8);case 2:result |= ((int)value[1] << 16);case 1:result |= ((int)value[0] << 24);break;default:throw new IllegalArgumentException('Invalid array size');}return result;}private static class JavaMemoryTrade{private long tradeId;private long clientId;private int venueCode;private int instrumentCode;private long price;private long quantity;private char side;public long getTradeId(){return tradeId;}public void setTradeId(final long tradeId){this.tradeId = tradeId;}public long getClientId(){return clientId;}public void setClientId(final long clientId){this.clientId = clientId;}public int getVenueCode(){return venueCode;}public void setVenueCode(final int venueCode){this.venueCode = venueCode;}public int getInstrumentCode(){return instrumentCode;}public void setInstrumentCode(final int instrumentCode){this.instrumentCode = instrumentCode;}public long getPrice(){return price;}public void setPrice(final long price){this.price = price;}public long getQuantity(){return quantity;}public void setQuantity(final long quantity){this.quantity = quantity;}public char getSide(){return side;}public void setSide(final char side){this.side = side;}}
}

緊湊型堆外結構

import sun.misc.Unsafe;import java.lang.reflect.Field;public class TestDirectMemoryLayout
{private static final Unsafe unsafe;static{try{Field field = Unsafe.class.getDeclaredField('theUnsafe');field.setAccessible(true);unsafe = (Unsafe)field.get(null);}catch (Exception e){throw new RuntimeException(e);}}private static final int NUM_RECORDS = 50 * 1000 * 1000;private static long address;private static final DirectMemoryTrade flyweight = new DirectMemoryTrade();public static void main(final String[] args){for (int i = 0; i < 5; i++){System.gc();perfRun(i);}}private static void perfRun(final int runNum){long start = System.currentTimeMillis();init();System.out.format('Memory %,d total, %,d free\n',Runtime.getRuntime().totalMemory(),Runtime.getRuntime().freeMemory());long buyCost = 0;long sellCost = 0;for (int i = 0; i < NUM_RECORDS; i++){final DirectMemoryTrade trade = get(i);if (trade.getSide() == 'B'){buyCost += (trade.getPrice() * trade.getQuantity());}else{sellCost += (trade.getPrice() * trade.getQuantity());}}long duration = System.currentTimeMillis() - start;System.out.println(runNum + ' - duration ' + duration + 'ms');System.out.println('buyCost = ' + buyCost + ' sellCost = ' + sellCost);destroy();}private static DirectMemoryTrade get(final int index){final long offset = address + (index * DirectMemoryTrade.getObjectSize());flyweight.setObjectOffset(offset);return flyweight;}public static void init(){final long requiredHeap = NUM_RECORDS * DirectMemoryTrade.getObjectSize();address = unsafe.allocateMemory(requiredHeap);final byte[] londonStockExchange = {'X', 'L', 'O', 'N'};final int venueCode = pack(londonStockExchange);final byte[] billiton = {'B', 'H', 'P'};final int instrumentCode = pack( billiton);for (int i = 0; i < NUM_RECORDS; i++){DirectMemoryTrade trade = get(i);trade.setTradeId(i);trade.setClientId(1);trade.setVenueCode(venueCode);trade.setInstrumentCode(instrumentCode);trade.setPrice(i);trade.setQuantity(i);trade.setSide((i & 1) == 0 ? 'B' : 'S');}}private static void destroy(){unsafe.freeMemory(address);}private static int pack(final byte[] value){int result = 0;switch (value.length){case 4:result |= (value[3]);case 3:result |= ((int)value[2] << 8);case 2:result |= ((int)value[1] << 16);case 1:result |= ((int)value[0] << 24);break;default:throw new IllegalArgumentException('Invalid array size');}return result;}private static class DirectMemoryTrade{private static long offset = 0;private static final long tradeIdOffset = offset += 0;private static final long clientIdOffset = offset += 8;private static final long venueCodeOffset = offset += 8;private static final long instrumentCodeOffset = offset += 4;private static final long priceOffset = offset += 4;private static final long quantityOffset = offset += 8;private static final long sideOffset = offset += 8;private static final long objectSize = offset += 2;private long objectOffset;public static long getObjectSize(){return objectSize;}void setObjectOffset(final long objectOffset){this.objectOffset = objectOffset;}public long getTradeId(){return unsafe.getLong(objectOffset + tradeIdOffset);}public void setTradeId(final long tradeId){unsafe.putLong(objectOffset + tradeIdOffset, tradeId);}public long getClientId(){return unsafe.getLong(objectOffset + clientIdOffset);}public void setClientId(final long clientId){unsafe.putLong(objectOffset + clientIdOffset, clientId);}public int getVenueCode(){return unsafe.getInt(objectOffset + venueCodeOffset);}public void setVenueCode(final int venueCode){unsafe.putInt(objectOffset + venueCodeOffset, venueCode);}public int getInstrumentCode(){return unsafe.getInt(objectOffset + instrumentCodeOffset);}public void setInstrumentCode(final int instrumentCode){unsafe.putInt(objectOffset + instrumentCodeOffset, instrumentCode);}public long getPrice(){return unsafe.getLong(objectOffset + priceOffset);}public void setPrice(final long price){unsafe.putLong(objectOffset + priceOffset, price);}public long getQuantity(){return unsafe.getLong(objectOffset + quantityOffset);}public void setQuantity(final long quantity){unsafe.putLong(objectOffset + quantityOffset, quantity);}public char getSide(){return unsafe.getChar(objectOffset + sideOffset);}public void setSide(final char side){unsafe.putChar(objectOffset + sideOffset, side);}}
}

結果

Intel i7-860 @ 2.8GHz, 8GB RAM DDR3 1333MHz, 
Windows 7 64-bit, Java 1.7.0_07
=============================================
java -server -Xms4g -Xmx4g TestJavaMemoryLayout
Memory 4,116,054,016 total, 1,108,901,104 free
0 - duration 19334ms
Memory 4,116,054,016 total, 1,109,964,752 free
1 - duration 14295ms
Memory 4,116,054,016 total, 1,108,455,504 free
2 - duration 14272ms
Memory 3,817,799,680 total, 815,308,600 free
3 - duration 28358ms
Memory 3,817,799,680 total, 810,552,816 free
4 - duration 32487msjava -server TestDirectMemoryLayout
Memory 128,647,168 total, 126,391,384 free
0 - duration 983ms
Memory 128,647,168 total, 126,992,160 free
1 - duration 958ms
Memory 128,647,168 total, 127,663,408 free
2 - duration 873ms
Memory 128,647,168 total, 127,663,408 free
3 - duration 886ms
Memory 128,647,168 total, 127,663,408 free
4 - duration 884msIntel i7-2760QM @ 2.40GHz, 8GB RAM DDR3 1600MHz, 
Linux 3.4.11 kernel 64-bit, Java 1.7.0_07
=================================================
java -server -Xms4g -Xmx4g TestJavaMemoryLayout
Memory 4,116,054,016 total, 1,108,912,960 free
0 - duration 12262ms
Memory 4,116,054,016 total, 1,109,962,832 free
1 - duration 9822ms
Memory 4,116,054,016 total, 1,108,458,720 free
2 - duration 10239ms
Memory 3,817,799,680 total, 815,307,640 free
3 - duration 21558ms
Memory 3,817,799,680 total, 810,551,856 free
4 - duration 23074msjava -server TestDirectMemoryLayout 
Memory 123,994,112 total, 121,818,528 free
0 - duration 634ms
Memory 123,994,112 total, 122,455,944 free
1 - duration 619ms
Memory 123,994,112 total, 123,103,320 free
2 - duration 546ms
Memory 123,994,112 total, 123,103,320 free
3 - duration 547ms
Memory 123,994,112 total, 123,103,320 free
4 - duration 534ms


分析

讓我們將結果與上面承諾的3個好處進行比較。

1.顯著改善性能

這里的證據很明確。 使用堆外結構方法要快一個數量級以上。 最極端的情況是,在Sandy Bridge處理器上運行第五 ,完成任務所需的時間相差43.2 。 這也很好地說明了Sandy Bridge在可預測的數據訪問模式方面的表現。 性能不僅明顯更好,而且更加一致。 隨著堆變得碎片化,因此訪問模式變得更加隨機,性能會下降,這在以后使用標準Java方法運行時可以看到。

2.更緊湊的數據表示

對于我們的堆外表示,每個對象需要42個字節。 如示例所示,要存儲其中的5000萬個字節,我們需要2100,000,000字節。 JVM堆所需的內存為:

所需內存=總內存–可用內存–基本JVM需求

2,883,248,712 = 3,817,799,680 – 810,551,856 – 123,999,112

這意味著JVM需要多40%的內存來表示相同的數據。 產生這種開銷的原因是對Java對象的引用數組以及對象標頭。 在上一篇文章中,我討論了Java中的對象布局。

當處理非常大的數據集時,此開銷可能成為重要的限制因素。

3.能夠處理非常大的數據集,同時避免令人討厭的GC暫停

上面的示例代碼在每次運行之前強制執行GC循環,并且在某些情況下可以提高結果的一致性。 隨時刪除對System.gc()的調用,并親自觀察其中的含義。 如果運行添加以下命令行參數的測試,則垃圾收集器將詳細輸出發生的情況。

-XX:+ PrintGC -XX:+ PrintGCDetails -XX:+ PrintGCDateStamps -XX:+ PrintTenuringDistribution -XX:+ PrintHeapAtGC -XX:+ PrintGCApplicationConcurrentTime -XX:+ PrintGCApplicationStoppedTime -XX:+ PrintSafepointStatistics

通過分析輸出,我可以看到該應用程序總共進行了29個GC循環。 通過從輸出中提取指示應用程序線程何時停止的行,下面列出了暫停時間。

With System.gc() before each run
================================
Total time for which application threads were stopped: 0.0085280 seconds
Total time for which application threads were stopped: 0.7280530 seconds
Total time for which application threads were stopped: 8.1703460 seconds
Total time for which application threads were stopped: 5.6112210 seconds
Total time for which application threads were stopped: 1.2531370 seconds
Total time for which application threads were stopped: 7.6392250 seconds
Total time for which application threads were stopped: 5.7847050 seconds
Total time for which application threads were stopped: 1.3070470 seconds
Total time for which application threads were stopped: 8.2520880 seconds
Total time for which application threads were stopped: 6.0949910 seconds
Total time for which application threads were stopped: 1.3988480 seconds
Total time for which application threads were stopped: 8.1793240 seconds
Total time for which application threads were stopped: 6.4138720 seconds
Total time for which application threads were stopped: 4.4991670 seconds
Total time for which application threads were stopped: 4.5612290 seconds
Total time for which application threads were stopped: 0.3598490 seconds
Total time for which application threads were stopped: 0.7111000 seconds
Total time for which application threads were stopped: 1.4426750 seconds
Total time for which application threads were stopped: 1.5931500 seconds
Total time for which application threads were stopped: 10.9484920 seconds
Total time for which application threads were stopped: 7.0707230 secondsWithout System.gc() before each run
===================================
Test run times
0 - duration 12120ms
1 - duration 9439ms
2 - duration 9844ms
3 - duration 20933ms
4 - duration 23041msTotal time for which application threads were stopped: 0.0170860 seconds
Total time for which application threads were stopped: 0.7915350 seconds
Total time for which application threads were stopped: 10.7153320 seconds
Total time for which application threads were stopped: 5.6234650 seconds
Total time for which application threads were stopped: 1.2689950 seconds
Total time for which application threads were stopped: 7.6238170 seconds
Total time for which application threads were stopped: 6.0114540 seconds
Total time for which application threads were stopped: 1.2990070 seconds
Total time for which application threads were stopped: 7.9918480 seconds
Total time for which application threads were stopped: 5.9997920 seconds
Total time for which application threads were stopped: 1.3430040 seconds
Total time for which application threads were stopped: 8.0759940 seconds
Total time for which application threads were stopped: 6.3980610 seconds
Total time for which application threads were stopped: 4.5572100 seconds
Total time for which application threads were stopped: 4.6193830 seconds
Total time for which application threads were stopped: 0.3877930 seconds
Total time for which application threads were stopped: 0.7429270 seconds
Total time for which application threads were stopped: 1.5248070 seconds
Total time for which application threads were stopped: 1.5312130 seconds
Total time for which application threads were stopped: 10.9120250 seconds
Total time for which application threads were stopped: 7.3528590 seconds

從輸出中可以看出,垃圾回收器花費了大量時間。 當線程停止時,您的應用程序無響應。 這些測試已使用默認GC設置完成。 可以調整GC以獲得更好的結果,但這可能是一項非常熟練的工作。 我知道,即使在高吞吐量條件下,即使不在高吞吐量條件下也不施加較長的暫停時間,這可以很好地應對JVM。

在對該應用程序進行性能分析時,我可以看到大部分時間都花在分配對象并將它們提升到老一代,因為它們不適合年輕一代。 可以從計時中除去初始化成本,但這是不現實的。 如果采用傳統的Java方法,則需要先建立狀態,然后才能進行查詢。 應用程序的最終用戶必須等待狀態建立和查詢執行。

這個測試確實非常簡單。 想象一下使用100 GB規模的相似數據集。

注意:當垃圾收集器壓縮區域時,可以將彼此相鄰的對象移開很遠。 這可能會導致TLB和其他緩存未命中。

關于序列化的旁注

以這種方式使用堆外結構的一個巨大好處是,如何通過簡單的內存副本將它們很容易地序列化到網絡或存儲中,就像我在上一篇文章中所展示的那樣。 這樣,我們可以完全繞過中間緩沖區和對象分配。

結論

如果您愿意對大型數據集進行一些C風格的編程,則可以通過脫離堆控制Java中的內存布局。 如果這樣做,那么在性能,緊湊性和避免GC問題方面的好處就非常重要。 但是,這種方法應該用于所有應用程序。 僅對于非常大的數據集或吞吐量和/或延遲的極端性能,才注意到它的優勢。

我希望Java社區可以共同認識到支持在堆和堆棧上的結構的重要性。 John Rose在這方面做了出色的工作 ,定義了如何將元組添加到JVM。 他今年在JVM語言峰會上發表的有關Arrays 2.0的演講確實值得關注。 約翰在演講中討論了結構數組的選擇和數組結構。 如果有John提出的元組可用,則此處描述的測試可以具有可比的性能,并且是更令人愉快的編程風格。 整個結構數組可以在一個動作中分配,從而繞開了跨代的單個對象的副本,并且可以緊湊的連續方式進行存儲。 這將消除此類問題中的重大GC問題。

最近,我比較了Java和.Net之間的標準數據結構。 在某些情況下,當.Net使用本機結構支持時,對于諸如地圖和字典之類的東西,我發現.Net的性能優勢是6-10倍。 讓我們盡快將其納入Java!

從結果也很明顯,如果我們要使用Java對大數據進行實時分析,那么我們的標準垃圾收集器就需要顯著改善并支持真正的并發操作。

[1] –據我所知,唯一處理非常大堆的JVM是Azul Zing

祝您編程愉快,別忘了分享!

參考:來自Java的JCG合作伙伴 Martin Thompson在Mechanical Sympathy博客上的緊湊型堆外結構/堆棧在Java中 。


翻譯自: https://www.javacodegeeks.com/2012/10/compact-off-heap-structurestuples-in.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371038.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371038.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371038.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java字符集編碼是,java字符集與編碼有關問題

java字符集與編碼問題沒想到自己的第一篇javaeye博客就是讓人頭痛的java字符集轉碼問題&#xff0c;下面是我個人的一些認識與網上收集的代碼。在java中String在JVM里是unicode的&#xff0c;任何byte[]到String以及String到byte[]都涉及到字符集編碼轉換。基本規則是&#xff…

mysql序列號生成_一文看懂mycat的6種全局序列號實現方式

概述在實現分庫分表的情況下&#xff0c;數據庫自增主鍵已無法保證自增主鍵的全局唯一。為此&#xff0c;MyCat 提供了全局sequence&#xff0c;并且提供了包含本地配置和數據庫配置等多種實現方式。下面對這幾種實現方式做一下介紹。1、本地文件方式原理&#xff1a;此方式 My…

android.graphics.Paint方法setXfermode (Xfermode x...

[java] view plaincopymPaint new Paint(); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN)); 常見的Xfermode&#xff08;SRC為原圖&#xff0c;DST為目標圖&#xff09;&#xff0c;把代碼中的SRC_IN換成下圖指定的模式就會出現對應的效果圖…

從零開始的全棧工程師——html篇1

全棧工程師也可以叫web 前端 H5主要是網站 app 小程序 公眾號這一塊 HTML篇 html(超文本標記語言&#xff0c;標記通用標記語言下的一個應用。) “超文本”就是指頁面內可以包含圖片、鏈接&#xff0c;甚至音樂、程序等非文字元素。 超文本標記語言的結構包括“頭”部分&am…

二分+樹的直徑 [Sdoi2011]消防

問題 D: [Sdoi2011]消防 時間限制: 1 Sec 內存限制: 512 MB 提交: 12 解決: 6 [提交][狀態][討論版] 題目描述 某個國家有n個城市&#xff0c;這n個城市中任意兩個都連通且有唯一一條路徑&#xff0c;每條連通兩個城市的道路的長度為zi(zi<1000)。 這個國家的人對火焰…

使用MRUnit測試Hadoop程序

這篇文章將略微繞開使用MapReduce實現數據密集型處理中的模式&#xff0c;以討論同樣重要的測試。 湯姆?惠勒 &#xff08; Tom Wheeler&#xff09;在紐約2012年Strata / Hadoop World會議上參加的一次演講給了我部分啟發。 處理大型數據集時&#xff0c;想到的并不是單元測試…

android之 TextWatcher的監聽

以前用過android.text.TextWatcher來監聽文本發生變化&#xff0c;但沒有仔細去想它&#xff0c;今天興致來了就發個瘋來玩玩吧&#xff01; 有點擔心自己理解錯&#xff0c;所以還是先把英文API解釋給大家看看 1、什么情況下使用了&#xff1f; When an object of a type is a…

php 秒殺并發怎么做,PHP實現高并發下的秒殺功能–Laravel

namespace App\Http\Controllers\SecKill;use App\Http\Controllers\Controller;use Exception;use Illuminate\Support\Facades\DB;use Illuminate\Support\Facades\Redis;class SecKillController extends Controller{/*** 往redis的隊列中添加庫存(用於測試的數據)**/public…

蘋果mp3軟件_優秀的Apple音樂轉換器,將任何iTunes M4P,AAX,AA轉換為MP3

Macsome iTunes Converter是一款優秀的音頻轉換工具&#xff0c;這款音頻轉換軟件能夠幫助大家快速進行音頻格式轉換&#xff0c;使得您可以自由的播放和分享自己喜愛的音頻文件。同時這款軟件與大多數音頻轉換軟件一樣&#xff0c;將受到保護DRM的Apple音樂轉換轉換成MP3, AAC…

Vuejs開發環境搭建及熱更新

一、安裝NPM 1.1最新穩定版本&#xff1a; npm install vue 二、命令行工具安裝 國內速度慢&#xff0c;使用淘寶鏡像&#xff1a; npm install -g cnpm --registryhttps://registry.npm.taobao.org 注意&#xff1a;以后使用npm的地方就替換成cnpm 1、全局安裝vue-vli ? …

線索二叉樹的C語言實現

#include "string.h"#include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1#define ERROR 0#define TRUE 1#define FALSE 0 #define MAXSIZE 100 /* 存儲空…

發送帶有接縫的活動邀請

這些天來&#xff0c;我的一位同事在使用帶有接縫&#xff08;2.x版&#xff09;的郵件模板發送事件邀請時遇到了問題。 從根本上講&#xff0c;這不是一個艱巨的任務&#xff0c;因此我將簡要說明使用接縫郵件模板發送事件邀請需要做什么。 發送郵件邀請時&#xff0c;您需要發…

Oracle內存管理(之二)

Oracle內存管理&#xff08;之二&#xff09; 【深入解析--eygle】 學習筆記 1.2.2 UGA和CGA UGA&#xff08;用戶全局區&#xff09;由用戶會話數據、游標狀態和索引區組成。在共享server模式下&#xff0c;一個共享服務進程被多個用戶進程共享&#xff0c;此時UGA是Shared Po…

matlab抓取股票數據,Matlab經過sina web接口獲取個數即時股票數據函數實現代碼

Matlab通過sina web接口獲取個數即時股票數據函數實現代碼代碼如下&#xff1a;function stockinfo queryprice(stocktype, stockid)%stocktype 股票類型&#xff1a;sh和sz%stockid 股票編碼&#xff1a;url sprintf(http://hq.sinajs.cn/list%s%d, stocktype, stockid);[so…

虛幻4毛發系統_虛幻引擎復活!蘋果與Epic對決,有哪些游戲險些中槍?

最近&#xff0c;蘋果和Epic的官司鬧得沸沸揚揚。隨著Epic旗下熱門手游《堡壘之夜》遭蘋果火速下架&#xff0c;兩大巨頭之間的沖突愈演愈烈。蘋果似乎并不滿足于此&#xff0c;由于Epic公開違反自家規定&#xff0c;蘋果計劃進一步封禁Epic維護虛幻引擎的開發者賬戶&#xff0…

史上最全的HTML和CSS標簽常用命名規則

文件夾主要建立以下文件夾&#xff1a;  1、Images 存放一些網站常用的圖片&#xff1b;  2、Css 存放一些CSS文件&#xff1b;  3、Flash 存放一些Flash文件&#xff1b;  4、PSD 存放一些PSD源文件&#xff1b;  5、Temp 存放所有臨時圖片和其它文件&#xff1b; …

01-JAVA語言基礎

1.設計思想&#xff1a; 先以字符串的形式輸入兩個數字&#xff0c;然后將他們轉化為int類型&#xff0c;再對兩數進行相加&#xff0c;最后輸出結果。 2.程序流程圖&#xff1a; 3.源程序代碼&#xff1a; import java.util.Scanner;public class Addition2 {public static vo…

與JodaTime的DateTime和Google Guava的供應商嘲笑

介紹 如果您是經驗豐富的單元測試人員&#xff0c;那么當您看到任何與時間 &#xff0c; 并發性 &#xff0c; 隨機性 &#xff0c; 持久性和磁盤I / O協同工作的代碼時&#xff0c;您就會學會做筆記。 原因是測試可能非常脆弱&#xff0c;有時完全無法正確測試。 這篇文章將展…

棧實現 C語言

最近上來寫了一下棧&#xff0c;理解數據結構的棧。 頭文件&#xff1a;stack.h 初始化棧結構與函數定義&#xff1a; #include<stdlib.h> #include <stdio.h> #include<memory.h> #define N 100struct stack {int data[N];int top;//標識棧頂 }; typedef s…

php簽名墻,肺功能檢查質量控制網

2017年12月2日&#xff0c;由中華醫學會呼吸病學分會/兒科分會、國家呼吸系統疾病臨床醫學研究中心、國家呼吸疾病醫療質量控制中心、中國肺功能聯盟、中國兒童肺功能協作組主辦&#xff0c;浙江省中醫院承辦的"2017年中國肺功能檢查規范化培訓及應用推廣學習班暨肺功能檢…