导航:首页 > 编程语言 > 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内存映射相关的资料

热点内容
成都市区建成面积算法 浏览:656
智能家居单片机 浏览:93
买男装用什么app好 浏览:851
文件夹合并了怎么拆开 浏览:256
波段副图源码无未来函数 浏览:84
livecn服务器地址 浏览:257
程序员这个工作真的很吃香吗 浏览:844
程序员和数学分析师待遇 浏览:678
压缩气弹簧怎么拆 浏览:321
华为公有云服务器添加虚拟ip 浏览:209
程序员和运营哪个累 浏览:24
抖音安卓信息提示音怎么设置 浏览:454
光速虚拟机的共享文件夹 浏览:248
程序员培训机构发的朋友圈真实性 浏览:742
天干地支简单算法 浏览:299
下载个压缩文件 浏览:300
普通人电脑关机vs程序员关机 浏览:628
米酷建站源码 浏览:115
氢气app怎么搜搭配 浏览:619
pdf绿盟 浏览:505