導航:首頁 > 編程語言 > java內存映射

java內存映射

發布時間:2022-06-29 15:18:14

1. 在java中,我們new一個對象, 就開辟一塊內存,請問這塊內存是JVM的內存,還是我們計算機的

虛擬機中的內存是與計算機的物理內存映射的。也就是說new是佔用虛擬機的內存,同時也佔用物理內存。

2. java讀取wis文件,用內存映射的方法,但是不知道wis二進制文件存儲時的具體格式,怎麼讀取呢

如果你要解析並且不知道具體格式的話,那就沒辦法了

3. 誰能用最通俗易懂的話告訴我JAVA中遍歷、迭代、映射的概念

數組就象是火車
遍歷就是把火車從頭到尾走一便
迭代是遍歷容器必須的跳板
用迭代才能遍歷
映射就想你操縱一個對象一樣,其實,你是在操作內存
也就是對象是那塊內存的映射

4. 內存映射是怎麼回事

內存映射文件是由一個文件到一塊內存的映射,使進程虛擬地址空間的某個區域與磁碟上某個文件的部分或全部內容的建立映射。
建立映射後,通過該區域可以直接對被映射的磁碟文件進行訪問.而不必執行文件I/O操作也無需對文件內容進行緩沖處理。
就好像整個被映射的文件都載入到了內存一樣,因此內存文件映射非常適合於用來管理大文件。

內存映射文件對程序的提速,只在處理大文件或非常頻繁的文件讀寫操作時效果才明顯。
通過內存映射,相當於將磁碟上的文件所在空間建立成一塊虛擬內存,程序訪問時可按內存的方式進行,省去了普通io方式的一些環節,其實真正要讀寫操作時,會進行換頁,將這些個「虛擬內存」讀到物理內存中。
總之,內存映射文件是應用虛擬內存的技術來達到加速處理的

5. java 進程間通訊的有幾種方法

進程間通信的方法主要有以下幾種:

(1)管道(Pipe):管道可用於具有親緣關系進程間的通信,允許一個進程和另一個與它有共同祖先的進程之間進行通信。
(2)命名管道(named pipe):命名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關 系進程間的通信。命名管道在文件系統中有對應的文件名。命名管道通過命令mkfifo或系統調用mkfifo來創建。
(3)信號(Signal):信號是比較復雜的通信方式,用於通知接受進程有某種事件發生,除了用於進程間通信外,進程還可以發送 信號給進程本身;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標準的信號函數sigaction(實際上,該函數是基於BSD的,BSD為了實現可靠信號機制,又能夠統一對外介面,用sigaction函數重新實現了signal函數)。
(4)消息(Message)隊列:消息隊列是消息的鏈接表,包括Posix消息隊列system V消息隊列。有足夠許可權的進程可以向隊列中添加消息,被賦予讀許可權的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式位元組流以及緩沖區大小受限等缺
(5)共享內存:使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對其他通信機制運行效率較低而設計的。往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。
(6)內存映射(mapped memory):內存映射允許任何多個進程間通信,每一個使用該機制的進程通過把一個共享的文件映射到自己的進程地址空間來實現它。
(7)信號量(semaphore):主要作為進程間以及同一進程不同線程之間的同步手段。
(8)套介面(Socket):更為一般的進程間通信機制,可用於不同機器之間的進程間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上:Linux和System V的變種都支持套接字。

而在java中我們實現多線程間通信則主要採用"共享變數"和"管道流"這兩種方法

方法一 通過訪問共享變數的方式(注:需要處理同步問題)
方法二 通過管道流

其中方法一有兩種實現方法,即
方法一a)通過內部類實現線程的共享變數
代碼如下:

public class Innersharethread {
public static void main(String[] args) {
Mythread mythread = new Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class Mythread {
int index = 0;
private class InnerThread extends Thread {
public synchronized void run() {
while (true) {
System.out.println(Thread.currentThread().getName()
+ "is running and index is " + index++);
}
}
}
public Thread getThread() {
return new InnerThread();
}
}
/**
* 通過內部類實現線程的共享變數
*
*/
public class Innersharethread {
public static void main(String[] args) {
Mythread mythread = new Mythread();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
mythread.getThread().start();
}
}
class Mythread {
int index = 0;
private class InnerThread extends Thread {
public synchronized void run() {
while (true) {
System.out.println(Thread.currentThread().getName()
+ "is running and index is " + index++);
}
}
}
public Thread getThread() {
return new InnerThread();
}
}

b)通過實現Runnable介面實現線程的共享變數
代碼如下:

public class Interfacaesharethread {
public static void main(String[] args) {
Mythread mythread = new Mythread();
new Thread(mythread).start();
new Thread(mythread).start();
new Thread(mythread).start();
new Thread(mythread).start();
}
}
/* 實現Runnable介面 */
class Mythread implements Runnable {
int index = 0;
public synchronized void run() {
while (true)
System.out.println(Thread.currentThread().getName() + "is running and
the index is " + index++);
}
}
/**
* 通過實現Runnable介面實現線程的共享變數
*/
public class Interfacaesharethread {
public static void main(String[] args) {
Mythread mythread = new Mythread();
new Thread(mythread).start();
new Thread(mythread).start();
new Thread(mythread).start();
new Thread(mythread).start();
}
}
/* 實現Runnable介面 */
class Mythread implements Runnable {
int index = 0;
public synchronized void run() {
while (true)
System.out.println(Thread.currentThread().getName() + "is running and
the index is " + index++);
}
}

方法二(通過管道流):
代碼如下:

public class CommunicateWhitPiping {
public static void main(String[] args) {
/**
* 創建管道輸出流
*/
PipedOutputStream pos = new PipedOutputStream();
/**
* 創建管道輸入流
*/
PipedInputStream pis = new PipedInputStream();
try {
/**
* 將管道輸入流與輸出流連接 此過程也可通過重載的構造函數來實現
*/
pos.connect(pis);
} catch (IOException e) {
e.printStackTrace();
}
/**
* 創建生產者線程
*/
Procer p = new Procer(pos);
/**
* 創建消費者線程
*/
Consumer c = new Consumer(pis);
/**
* 啟動線程
*/
p.start();
c.start();
}
}
/**
* 生產者線程(與一個管道輸入流相關聯)
*
*/
class Procer extends Thread {
private PipedOutputStream pos;
public Procer(PipedOutputStream pos) {
this.pos = pos;
}
public void run() {
int i = 8;
try {
pos.write(i);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 消費者線程(與一個管道輸入流相關聯)
*
*/
class Consumer extends Thread {
private PipedInputStream pis;
public Consumer(PipedInputStream pis) {
this.pis = pis;
}
public void run() {
try {
System.out.println(pis.read());
} catch (IOException e) {
e.printStackTrace();
}
}
}

6. java是不是沒有內存泄漏問題

Java中雖然使用了gc策略,但事實上還是會出現內存泄漏現象的,java因此還提出了弱引用等局部解決方案。

但樓主說的System.exit(0)是不會形成內存泄漏的。

其實這里都是兩個范疇的內存了。樓上以及我開始說的Java中的內存是指虛擬機的內存,映射到宿主機可以有各種實現,雖然一般也是映射到內存。 而System.exit(0)會析構掉虛擬機,也就是把這個虛擬的機器都拆了,也就無從談起虛擬機內存泄漏不泄漏的概念,正所謂皮之不存,毛將焉附。而問題是宿主機的內存是否泄漏了。從原理上說,虛擬機運行時,不管執行怎樣的指令,映射到宿主機器資源,都回在機器被拆掉時釋放。當然,從實現上說,如果宿主操作系統,或者JVM有bug,當然有可能造成內存泄漏,但和java程序員寫的客戶程序無關。(補充:包括在宿主機內殺java進程,其資源回收問題是操作系統和java平台的責任。我們在古老的操作系統經常會遇到文件沒正常關閉之類的問題,但現在的操作系統這些問題應該不會很大,也就是宿主機其實也有一定的回收機制,包括內存回收,但著本身不是內存泄漏的范疇,內存泄漏是指程序運行時的客戶程序造成的內存資源失控。當客戶程序退出時的問題,就是操作系統設計的范疇了)

7. java反射機制詳解

反射就是把Java的各種成分映射成相應的Java類。
Class類的構造方法是private,由JVM創建。
反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變數和方法並且顯示出來。Java 的這一能力在實際應用中也許用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。(來自Sun)
JavaBean 是 reflection 的實際應用之一,它能讓一些工具可視化的操作軟體組件。這些工具通過 reflection 動態的載入並取得 Java 組件(類) 的屬性。
反射是從1.2就有的,後面的三大框架都會用到反射機制,涉及到類"Class",無法直接new CLass(),其對象是內存里的一份位元組碼.
Class 類的實例表示正在運行的 Java 應用程序中的類和介面。枚舉是一種類,注釋是一種介面。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。
基本的 Java類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也表示為 Class 對象。Class 沒有公共構造方法。
Class 對象是在載入類時由 Java 虛擬機以及通過調用類載入器中的 defineClass 方法自動構造的。
Person p1 = new Person();
//下面的這三種方式都可以得到位元組碼
CLass c1 = Date.class();
p1.getClass();
//若存在則載入,否則新建,往往使用第三種,類的名字在寫源程序時不需要知道,到運行時再傳遞過來
Class.forName("java.lang.String");

Class.forName()位元組碼已經載入到java虛擬機中,去得到位元組碼;java虛擬機中還沒有生成位元組碼 用類載入器進行載入,載入的位元組碼緩沖到虛擬機中。
另外,大家可以關注微信公眾號Java技術棧回復:JVM,獲取我整理的系列JVM教程,都是干貨。
考慮下面這個簡單的例子,讓我們看看 reflection 是如何工作的。
import java.lang.reflect.*;

public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName("java.util.Stack");

Method m[] = c.getDeclaredMethods();

for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
}
catch (Throwable e){
System.err.println(e);
}
}
}

public synchronized java.lang.Object java.util.Stack.pop()
public java.lang.Object java.util.Stack.push(java.lang.Object)
public boolean java.util.Stack.empty()
public synchronized java.lang.Object java.util.Stack.peek()
public synchronized int java.util.Stack.search(java.lang.Object)

這樣就列出了java.util.Stack 類的各方法名以及它們的限制符和返回類型。這個程序使用 Class.forName 載入指定的類,然後調用 getDeclaredMethods 來獲取這個類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個類中單個方法的一個類。
以下示例使用 Class 對象來顯示對象的類名:
void printClassName(Object obj) {
System.out.println("The class of " + obj +
" is " + obj.getClass().getName());
}

還可以使用一個類字面值(JLS Section 15.8.2)來獲取指定類型(或 void)的 Class 對象。例如:
System.out.println("The name of class Foo is: "+Foo.class.getName());

在沒有對象實例的時候,主要有兩種辦法。
//獲得類類型的兩種方式
Class cls1 = Role.class;
Class cls2 = Class.forName("yui.Role");

注意第二種方式中,forName中的參數一定是完整的類名(包名+類名),並且這個方法需要捕獲異常。現在得到cls1就可以創建一個Role類的實例了,利用Class的newInstance方法相當於調用類的默認的構造器。
Object o = cls1.newInstance();
//創建一個實例
//Object o1 = new Role(); //與上面的方法等價

8. 如何理解java nio物理內存映射文件

JDK1.4版本引入了java.nio包,對文件流進行讀寫操作,提供無阻塞模式,同時也提供了一種高效率的文件讀寫模式,內存映射文件,把文件某個區域塊映射到內存,進行高效率的讀寫,主要用到下面類
java.nio.MappedByteBuffer;
java.nio.channels.FileChannel

9. 怎樣用Java獲取內存中的數據

可以考慮使用內存映射文件:java.nio.MappedByteBuffer,主要適合放入較大的數據進入系統內存
可以考慮使用:java.nio.ByteBuffer.allocateDirect()方法進行分配,可以將一些不適合放入堆里的數據放入系統內存
還可以採用java本地調用的方式,實現對系統自身內存的掌控與調度,這種方式可以讓你靈活的訪問系統的內存。
java的堆放入的對象尺度是有限制的,這里建議參考BigMemory 的實現機制以及內存管理機制
如果自己管理內存的話,建議參考其他語言對內存管理的方式。
你可以把數據放入線性數據結構中(這些數據是在系統內存中,而非jvm管理的內存里),這樣就不存在分代問題,可以由你的應用在適當的時候清理系統的內存。這樣,你的內存模型-釋放機制就與jvm的內存管理機制處於一個互不幹擾的異行線上。

10. 如何獲取到JAVA對象所在的內存地址

1、首先打開java構造方法代碼。

(10)java內存映射擴展閱讀


當使用80386時,必須區分以下三種不同的地址:

邏輯地址:機器語言指令仍用這種地址指定一個操作數的地址或一條指令的地址。這種定址方式在Intel的分段結構中表現得尤為具體,它使得MS-DOS或Windows程序員把程序分為若干段。每個邏輯地址都由一個段和偏移量組成。

線性地址:針對32位CPU,線性地址是一個32位的無符號整數,可以表達高達2³² (4GB)的地址。通常用16進製表示線性地址,其取值范圍為0x00000000~0xffffffff。對64位CPU,線性地址是一個64位的無符號整數,可以表達高達2⁶⁴ 。

物理地址:也就是內存單元的實際地址,用於晶元級內存單元定址。物理地址也由32位無符號整數表示。

電腦的內存(尤其是指主存)是由許多「內存地址」所組成的,每個內存地址都有一個「物理地址」,能供CPU(或其他設備)訪問。一般,只有如BIOS、操作系統及部分特定之公用軟體(如內存測試軟體)等系統軟體;

能使用機器碼的運算對象或寄存器對物理地址定址,指示CPU要求內存控制器之類的硬體設備,使用內存匯流排或系統匯流排,亦或分別之控制匯流排、地址匯流排及數據匯流排,運行該程序之命令。

內存控制器的匯流排是由數條並行的線路所組成的,每條線路表示一個比特。匯流排的寬度因此依電腦不同,決定了可定址之存儲單位數量,以及每一單位內的比特數量。

計算機程序使用內存地址來運行機器碼、存儲及截取數據。大多數的應用程序無法得知實際的物理地址,而是使用電腦的內存管理單元及操作系統的內存映射,為「邏輯地址」或虛擬地址定址。

閱讀全文

與java內存映射相關的資料

熱點內容
不去互聯網程序員 瀏覽:550
電腦qq郵箱解壓的圖片保存在哪裡 瀏覽:544
嵌入命令行 瀏覽:91
檔案為什麼被加密 瀏覽:485
十天學會單片機13 瀏覽:875
榮耀怎麼設置讓app一直運行 瀏覽:992
共享文件夾能在哪裡找到 瀏覽:435
旅遊訂旅店用什麼app 瀏覽:239
一個女程序員的聲音 瀏覽:496
魔術app怎麼用 瀏覽:340
單片機有4個8位的io口 瀏覽:897
win10rar解壓縮軟體 瀏覽:169
plc教程pdf 瀏覽:668
pythonshell清屏命令 瀏覽:279
檢測到加密狗注冊伺服器失敗 瀏覽:205
解壓後手機如何安裝 瀏覽:519
極客學院app為什麼下架 瀏覽:14
圖片批量壓縮綠色版 瀏覽:656
東北程序員帥哥 瀏覽:709
加密封條風噪小 瀏覽:975