Java内存与Windows

Java内存与Windows,java,windows,memory,Java,Windows,Memory,今天注意到了一些有意义的东西,但我不能准确地解释语义 基本上,我创建了一个普通的javamain方法,其中有一个永无止境的while循环。在这个循环中,我创建了一些字符串并将它们放在HashMap中。我真正想要的是一个在一段时间内运行并提高内存利用率的过程 public class Test { public static void main(String[] args) throws InterruptedException { final HashMap<String, St

今天注意到了一些有意义的东西,但我不能准确地解释语义

基本上,我创建了一个普通的java
main
方法,其中有一个永无止境的while循环。在这个循环中,我创建了一些字符串并将它们放在HashMap中。我真正想要的是一个在一段时间内运行并提高内存利用率的过程

public class Test {

public static void main(String[] args) throws InterruptedException {
    final HashMap<String, String> names = new HashMap<String, String>();
    while(true) {
        names.put(new Date().toString(), "lskjflksjdflksjdflkjsieurlskjflksn,kdsgkjsdlkfjslkdjfs");
        Thread.sleep(50);
    }
}
公共类测试{
公共静态void main(字符串[]args)引发InterruptedException{
最终HashMap名称=新HashMap();
while(true){
name.put(new Date().toString(),“lskjflksjdflkskjdflkjsieurlskjflksn,kdsgkjsdlkfjslkdjfs”);
睡眠(50);
}
}
}

该过程从
-Xms512m-Xmx512m
开始

一旦启动,我就可以使用
procexp.exe
查看我的java进程。我想了解的是虚拟内存和物理内存。虚拟内存(专用字节)似乎映射到请求的jvm大小,即512MB。从进程随时间变化的概况来看,我假设物理内存(工作集)是进程使用的实际内存,因为随着进程生成更多字符串值并填充映射,物理内存会随时间逐渐增加。它总是比512MB小很多

所以我的问题是,为什么Java使用虚拟内存

它不是全部在RAM中,即物理内存中吗

因为我正在使用虚拟内存,这是否意味着它正在交换到磁盘

这对性能不好吗

有没有一种方法可以强制所有的东西都在RAM中以获得更好的性能


任何关于Windows上此类内容的好文章都会很棒。

对于32位计算机上的每个进程,可寻址内存是4GB,计算机是否实际具有4GB的RAM内存并不重要

例如,如果您的计算机有2GB的RAM,对于JVM来说,它看起来有4GB的内存。另一个2GB内存来自将内存映射到HDD中的文件(这是虚拟内存)

如果有多个进程在运行,对于每个进程,它似乎是计算机上运行的唯一进程,有4GB的可寻址内存。由于JVM不是唯一运行的进程,操作系统中的内存管理器可能会决定将未使用内存的内容推送到虚拟内存文件中。这由操作系统决定

由于它正在交换到磁盘,性能的滞后将是显而易见的(除非它是固态硬盘驱动器)

为什么Java使用虚拟内存

所有用户应用程序都使用虚拟内存与操作系统内存交互。由操作系统将其映射回物理RAM/磁盘(通过页表)。因为JVM是用-Xms512m启动的,所以启动时它会请求500 MB的虚拟内存空间,但操作系统选择不为此保留500 MB的物理RAM,因为它可能永远不会被使用

它不是全部在RAM中,即物理内存中吗

除非您的机器使用的物理RAM百分比很高(>75%左右),并且基于JVM的应用程序最近访问了它的一些数据,否则JVM将全部在RAM中

因为我正在使用虚拟内存,这是否意味着它正在交换到磁盘

不,见上文

这对性能不好吗

在将数据分页到磁盘的应用程序中,分页可能会影响性能。Windows将通过以下两种方式尽量减少这种影响:

  • 发送到磁盘的虚拟内存页是最近使用最少的页
  • 如果Windows能够检测到某个页面即将被使用,那么有几种优化设计可以将该页面从磁盘上拉回(即,如果您开始迭代地图中的键,那么Windows将尝试在迭代到达下一个键块之前拉回包含下一个键块的页面)
  • 另外,正如我提到的,您很可能没有分页到磁盘

    有没有一种方法可以强制所有的东西都在RAM中以获得更好的性能

    您可以在windows中关闭页面文件

    任何关于Windows上此类内容的好文章都将非常好


    我建议使用VisualVM观察这个过程。GC将确保每个页面都被触摸并强制进入内存。JVM可能在RAM中,但对象可能不在内存中。。有些可能会放在虚拟内存文件中谢谢@Ryan。你说分页不好。我还通过procexp.exe看到页面错误,因为存在+ve增量,这是否意味着我正在分页?有时Windows会开始分页最近没有使用过的数据,即使您只使用了较小比例的物理RAM。如果在任务管理器中看到页面错误,则Windows正在为应用程序分页。