直接缓冲区
direct buffer是通常用于将Java与OS I / O子系统进行接口的内存块,例如作为操作系统在从套接字或磁盘接收数据时从其中读取数据的位置,以及哪些Java可以直接读取。
与操作系统共享缓冲区比将数据从操作系统复制到Java内存模型的原始方法要高得多,从而使数据受到垃圾收集和低效率的影响,例如从eden迁移时重新复制数据, >幸存者 – >终身 – >给永久的一代。
在截图中,您只有一个缓冲区为16KB的直接缓冲区。 Java将根据需要增长这个池,所以蓝色区域位于块顶部的事实只是一个声明,所有缓冲区内存被分配到目前为止。我不认为这是一个问题。
映射缓冲池
映射的缓冲池是Java为其FileChannel实例使用的所有内存。
每个FileChannel实例都有与操作系统共享的缓冲区(类似于具有所有效率优势的直接缓冲区)。内存本质上是一个RAM内的窗口到文件的一部分。根据模式(读,写或两者),Java可以直接读取和/或修改文件的内容,并且操作系统可以直接提供数据或将修改的数据刷新到磁盘。
这种方法的其他优点是,操作系统可以将该缓冲区直接刷新到磁盘,例如当操作系统关闭时,操作系统可以将该文件的该部分从计算机上的其他进程锁定。
屏幕截图表示您有12个FileChannel对象使用大约680MB。再次,Java将会增长这是Scala需要更多(并且JVM可以从操作系统获得额外的内存),所以所有680MB都在使用的事实并不重要。鉴于它们的大小,在我看来,程序已经被优化以有效地使用这些缓冲区。
增加映射缓冲池的大小
Java为FileChannel缓冲区的Garbage Collection空间分配内存。这意味着正常的堆大小参数(如-Xmx)在这里并不重要
FileChannel中缓冲区的大小由map方法设置。改变这一切将需要改变您的Scala程序
一旦缓冲区达到了大小为10s-100s的KB的阈值大小,则增加FileChannel缓冲区大小可能或可能不会提高性能 – 这取决于程序如何使用缓冲区:
>否:如果文件从头到尾精确读取一次:几乎所有的时间都在等待磁盘或处理算法
>也许:如果算法经常扫描文件重访部分多次,增加大小可能会提高性能:
>如果修改或写入文件,较大的缓冲区可以将更多的写入整合到一个单独的冲洗中。
>如果读取文件,操作系统可能已经缓存了文件(磁盘缓存),所以任何收益都可能是边际的。通过缩小有效的磁盘缓存大小,反过来增加JVM的大小可能会降低性能
>在任何情况下,应用程序必须特别编码以获得任何好处,例如通过在缓存上实现自己的逻辑记录指针。
尝试分析应用程序并查找I / O等待(Jprofiler和YourKit都很好)。这可能是文件I / O实际上不是问题 – 不要成为premature optimization的受害者。如果I / O等待是总时间的重要部分,那么可能值得尝试一个更大的缓冲区大小
更多信息