使用內存映射文件獲取巨大的矩陣

總覽

矩陣可能真的很大,有時甚至比一個數組中可以容納的更大。 您可以通過具有多個數組來擴展最大大小,但這會使堆大小確實很大且效率低下。 一種替代方法是在內存映射文件上使用包裝器。 內存映射文件的優點是它們對堆的影響很小,并且可以由操作系統相當透明地交換出來。

巨大的矩陣

此代碼支持double的大型矩陣。 它將文件分區為1 GB映射。 (由于Java一次不支持2 GB或更大的映射,這是我的寵兒;)

import sun.misc.Cleaner;
import sun.nio.ch.DirectBuffer;import java.io.Closeable;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;public class LargeDoubleMatrix implements Closeable {private static final int MAPPING_SIZE = 1 << 30;private final RandomAccessFile raf;private final int width;private final int height;private final List mappings = new ArrayList();public LargeDoubleMatrix(String filename, int width, int height) throws IOException {this.raf = new RandomAccessFile(filename, "rw");try {this.width = width;this.height = height;long size = 8L * width * height;for (long offset = 0; offset < size; offset += MAPPING_SIZE) {long size2 = Math.min(size - offset, MAPPING_SIZE);mappings.add(raf.getChannel().map(FileChannel.MapMode.READ_WRITE, offset, size2));}} catch (IOException e) {raf.close();throw e;}}protected long position(int x, int y) {return (long) y * width + x;}public int width() {return width;}public int height() {return height;}public double get(int x, int y) {assert x >= 0 && x < width;assert y >= 0 && y < height;long p = position(x, y) * 8;int mapN = (int) (p / MAPPING_SIZE);int offN = (int) (p % MAPPING_SIZE);return mappings.get(mapN).getDouble(offN);}public void set(int x, int y, double d) {assert x >= 0 && x < width;assert y >= 0 && y < height;long p = position(x, y) * 8;int mapN = (int) (p / MAPPING_SIZE);int offN = (int) (p % MAPPING_SIZE);mappings.get(mapN).putDouble(offN, d);}public void close() throws IOException {for (MappedByteBuffer mapping : mappings)clean(mapping);raf.close();}private void clean(MappedByteBuffer mapping) {if (mapping == null) return;Cleaner cleaner = ((DirectBuffer) mapping).cleaner();if (cleaner != null) cleaner.clean();}
}public class LargeDoubleMatrixTest {@Testpublic void getSetMatrix() throws IOException {long start = System.nanoTime();final long used0 = usedMemory();LargeDoubleMatrix matrix = new LargeDoubleMatrix("ldm.test", 1000 * 1000, 1000 * 1000);for (int i = 0; i < matrix.width(); i++)matrix.set(i, i, i);for (int i = 0; i < matrix.width(); i++)assertEquals(i, matrix.get(i, i), 0.0);long time = System.nanoTime() - start;final long used = usedMemory() - used0;if (used == 0)System.err.println("You need to use -XX:-UseTLAB to see small changes in memory usage.");System.out.printf("Setting the diagonal took %,d ms, Heap used is %,d KB%n", time / 1000 / 1000, used / 1024);matrix.close();}private long usedMemory() {return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();}
}

通過以下測試,該測試將一百萬*一百萬矩陣的每個對角線值寫入。 這太大了,無法希望在堆上創建。

Setting the diagonal took 314,819 ms, Heap used is 2,025 KB$ ls -l ldm.test
-rw-rw-r-- 1 peter peter 8000000000000 2011-12-30 12:42 ldm.test
$ du -s ldm.test 
4010600 ldm.test

在Java進程中,虛擬內存為8,000,000,000,000字節或?7.3 TB! 這行得通,因為它僅在您使用的頁面中分配或分配頁面。 因此,盡管文件大小幾乎為8 TB,但實際使用的磁盤空間和內存為4 GB。
使用100K * 100K矩陣的較小文件大小,您將看到類似以下的內容。 它仍然是一個80 GB的矩陣,使用了很小的堆空間。 ;)

Setting the diagonal took 110 ms, Heap used is 71 KB$ ls -l ldm.test
-rw-rw-r-- 1 peter peter 80000000000 2011-12-30 12:49 ldm.test
$ du -s ldm.test 
400000 ldm.test

參考:在Vanilla Java博客上,使用我們的JCG合作伙伴 Peter Lawrey 的巨大內存矩陣的內存映射文件

相關文章 :

  • 如何在Java中獲得類似于C的性能
  • Java中的低GC:使用原語而不是包裝器
  • 回收對象以提高性能
  • 改善Java應用程序性能的快速技巧
  • Java Secret:加載和卸載靜態字段
  • 具有GlassFish和一致性的高性能JPA –第1部分

翻譯自: https://www.javacodegeeks.com/2012/01/using-memory-mapped-file-for-huge.html

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

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

相關文章

ipad連接電腦_這些應用讓iPad生產力分分鐘UP

IT時報見習記者 錢奕昀用iPad辦公這件事&#xff0c;多年前網友就在討論&#xff0c;最常見的還是那句“買前生產力&#xff0c;買后愛奇藝”。很長一段時間里&#xff0c;它的生產力屬性都是弱于娛樂屬性的。其實&#xff0c;作為PC端和移動端的形態中和&#xff0c;iPad可以…

Mac OSX 快捷鍵命令行

ctrlshift 快速放大dock的圖標會暫時放大&#xff0c;而如果你開啟了dock放大CommandOptionW 將所有窗口關閉CommandW 將當前窗口關閉(可以關閉Safari標簽欄,很實用) CommandOptionM …

將JavaFX 2.0與Swing和SWT集成

JavaFX 2.0對JavaFX的改進之一是可以更輕松地與Swing和SWT進行互操作 。 一些在線資源記錄了如何完成此操作。 其中包括將JavaFX集成到Swing應用程序和SWT Interop中 。 但是&#xff0c;在有效的類級Javadoc文檔的一個很好的示例中&#xff0c;各自的JavaFX類javafx.embed.swi…

iOS-如何返回某個字符串的拼音助記碼

我也是看了網上的一個示例代碼后&#xff0c;在它的基礎上進行的修改。因為項目上會用到&#xff0c;我相信很多人的項目上也會用到。所以實現后&#xff0c;也趕緊分享出來&#xff0c;希望后來人不需要花費時間了。 提示&#xff1a;這里用到了正則表達式&#xff0c;使用了一…

wifi rssi 計算 距離_WiFi和WLAN是一樣的?真相在這里~別再傻傻分不清了

我們通常上網的時候會說連接WiFi如果注意到無線網絡的名稱就會發現手機的連接顯示是WLAN別再將WiFI和WLAN搞混了&#xff01;二者的定義WLANWLAN的全稱為 Wireless Local Area Networks,中文意思為無線局域網絡&#xff0c;是一種數據傳輸系統。它是利用射頻技術進行數據傳輸&a…

【Shell劇本練習】得出的結論是當前用戶

推斷是否當前用戶root。假設是暗示root用戶&#xff0c;假設而不是提示對于普通用戶#!/bin/bash #title: testus.sh #author: orangleliu #date: 2014-08-09 #desc: get current user, if it is root user, tell us it is super user or tell us is a common user# #Function C…

播放框架模塊:分而治之

通常情況是您開始開發應用程序并繼續滿足要求。 當您的應用程序變得更大時&#xff0c;您開始意識到將其分為不同組件的便利。 而且&#xff0c;當您開發第二個或第三個應用程序時&#xff0c;您開始認識到可以在不同應用程序之間重用的某些功能。 這是模塊化應用程序的兩個很好…

Alpha階段項目總結

1.我們的軟件要解決什么問題&#xff1f;是否定義得很清楚&#xff1f;是否對典型用戶和典型場景有清晰的描述&#xff1f; 我們的軟件是一款針對健康飲食而做的一款飲食健康軟件&#xff0c;對生活中我們經常遲到的很多事物組合都進行了詳細的注解&#xff0c;用戶可以清楚地看…

實用的it知識學習_怎樣能更快更好的學習好書法?分享一些比較實用的理論知識...

如何能更快更高效的學習書法&#xff1f;首先了解一些書法理論知識是很有必要的&#xff01;它能讓你在學習書法的過程中不至于迷茫 &#xff01;能助你更快學好書法&#xff01;一、書論在實踐中產生我們大部分人都覺得學習書法可以沒有理論&#xff0c;但不可無技法。但理論和…

九度oj-1001-Java

題目描述&#xff1a; This time, you are supposed to find AB where A and B are two matrices, and then count the number of zero rows and columns. 輸入&#xff1a; The input consists of several test cases, each starts with a pair of positive integers M and N …

字節流與字符流的區別

最近在項目中遇到一個encoding的問題&#xff0c;記錄一下。 具體而言就是&#xff0c;項目中有A/B兩個部分&#xff0c;A部分由我們負責&#xff0c;Java實現&#xff1b;B部分是UK負責的&#xff0c;使用Delphi&#xff0c;A、B在交互時發送一個http請求&#xff0c; 請求匯總…

通過MOXy實現使JAXB更加清潔

編組和解組XML時使用JAXB的主要優點是編程模型。 只需注釋幾個POJO并使用JAXB API&#xff0c;您就可以很容易地序列化為XML和從XML反序列化。 您無需擔心有關XML如何編組/解組的細節。 一切都比DOM和SAX等替代方案簡單得多。 現在&#xff0c;XML文件中的數據本質上趨于分層。…

android 上下滾動文字_計算機畢設項目004之Android系統在線小說閱讀器

計算機畢設項目004之Android系統在線小說閱讀器一. 項目名稱基于Android系統的在線小說閱讀器二. 項目簡介項目中的角色功能&#xff1a;支持翻頁動畫:仿真翻頁、覆蓋翻頁、上下滾動翻頁等翻頁效果。支持頁面定制:亮度調節、背景調節、字體大小調節支持全屏模式(含有虛擬按鍵的…

697. 數組的度

給定一個非空且只包含非負數的整數數組 nums&#xff0c;數組的 度 的定義是指數組里任一元素出現頻數的最大值。 你的任務是在 nums 中找到與 nums 擁有相同大小的度的最短連續子數組&#xff0c;返回其長度。 來源&#xff1a;力扣&#xff08;LeetCode&#xff09; 鏈接&a…

python math模塊

1.math簡介 >>> import math >>>dir(math) #這句可查看所有函數名列表 [__doc__, __name__, __package__, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, copysign, cos, cosh, degrees, e, erf, erfc, exp, expm1, fabs, factorial, flo…

Visual Studio找不到adb.exe錯誤解決

Visual Studio找不到adb.exe錯誤解決 錯誤信息&#xff1a;Cannot find adb.exe in specified SDK path。出現這種情況&#xff0c;是因為沒有安裝Android SDK Platform-tools。解決辦法&#xff1a;在SDK Manager中&#xff0c;安裝該組件即可。 轉載于:https://www.cnblogs.c…

Vaadin應用程序中的EJB查找

自從我實現上一個服務定位器以來已經有很長時間了。 我認為不再需要考慮Java EE CDI &#xff08;上下文和依賴注入&#xff09;的成熟度。 我的第一個實現是在基于Struts的Web應用程序中使用EJB。 之后&#xff0c;我開始使用JSF&#xff0c;它只需要帶有EJB或Resource的帶注釋…

基線檢查工具_最新版CAD燕秀工具箱2.87(支持20042021)

好課推薦&#xff1a;零基礎CAD&#xff1a;點我CAD家裝&#xff1a;點我 周站長CAD&#xff1a;點我CAD機械&#xff1a;點我revit教程&#xff1a;點我CAD建筑&#xff1a;點我CAD三維&#xff1a;點我全屋定制&#xff1a;點我 ps教程&#xff1a;點我蘋果版CAD:點我 3dmax教…

團隊項目記錄2

遇到的問題&#xff1a;在對Trigger機關進行測試時發現&#xff0c;畫出的軌道也會將機關觸發。 問題描述&#xff1a;Trigger機關的作用是在發生碰撞時運行腳本中指定的特定物體的特定函數&#xff0c;在這個例子當中特定的物體是一塊地板&#xff0c;特定的函數的功能是刪除這…

關于java.lang.ArithmeticException

java.lang.ArithmeticException “數學運算異常”&#xff0c;可能是自己的數學運算公式出現了錯誤、違反了數學運算規則。錯誤記錄&#xff1a; 出錯原因&#xff1a; a % b 中b不能為0