标签: directmemory

为Java应用程序设置MaxDirectMemory和MaxHeapMemory

对于我的Java应用程序,我试图使用命令行选项限制堆内存和直接内存使用.

当我试图了解有关Java应用程序内存布局的更多信息时,我遇到了以下VMware 文章.

从文章中,我假设-Xmx设置可用于限制堆使用,而MaxDirectMemory设置可用于限制堆外的本机内存(图中的Guest OS Memory).但是,当我运行一个简单的程序时,结果会有所不同.我使用ByteBuffer.allocateDirect分配本机内存,而ByteBuffer.allocate分配heapmemory.

它是64位处理器(OSX)和64位JVM.

第一次实验

import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.util.*;

public class javalimits {

    public static void main (String [] args)
            throws Exception {

            ArrayList al = new ArrayList();
            for(int i = 0; i< 100;i++) {

                    ByteBuffer bb = ByteBuffer.allocateDirect(1024 * 1024* 1024);
                    al.add(bb);
                    System.out.println(" Buffer loop "+ i);
                    Thread.sleep(500);
            }
            Thread.sleep(10000);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在没有任何选项的情况下运行上述程序时,它在3.6G的内存分配后崩溃了.当我使用"-XX:MaxDirectMemorySize = 100g"选项 "-Xms100g -Xmx100g"选项时,它在65次循环或大约65G内存分配后崩溃.

我不明白

  1. 由于我的物理内存仅为16G,为什么16G的内存分配后它没有崩溃?关于64G本机内存分配有什么特别之处?
  2. 当我使用"-Xms100g -Xmx100g"时,本机内存分配限制如何变化?我假设本机内存限制仅由选项""-XX:MaxDirectMemorySize = 100g"控制,根据我提供的链接中的上图.但是,结果不同.堆积内存设置也改变了直接内存缓冲区限制.
  3. 没有提供命令行选项时3.6G内存分配有什么特别之处?

第二次实验

我将ByteBuffer.allocateDirect更改为ByteBuffer.allocate,以便在堆内存而不是本机内存中进行分配.

import java.nio.ByteBuffer; …
Run Code Online (Sandbox Code Playgroud)

java memory memory-management heap-memory directmemory

8
推荐指数
1
解决办法
1427
查看次数

堆上java缓存有多少数据?什么时候应该开始考虑堆外缓存?

像ehcache这样的堆栈缓存有多少数据?

我得到一个24GB的RAM服务器.我可能会开始使用2-4 GB进行缓存,但最终可能会投入20GB左右来缓存.在什么时候我应该担心堆上缓存的GC需要太长时间?

那么,DirectMemory是唯一可用的开源堆外缓存吗?黄金时间准备好了吗?

java caching ehcache directmemory

6
推荐指数
1
解决办法
2540
查看次数

如何使用Java引用使用Java Unsafe释放内存?

Java Unsafe类允许您按如下方式为对象分配内存,但是使用此方法如何释放完成时分配的内存,因为它不提供内存地址...

    Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference
    f.setAccessible(true);
    Unsafe unsafe = (Unsafe) f.get(null);

    //This creates an instance of player class without any initialization
    Player p = (Player) unsafe.allocateInstance(Player.class);
Run Code Online (Sandbox Code Playgroud)

有没有办法从对象引用访问内存地址,也许默认的hashCode实现返回的整数可以工作,所以你可以做...

 unsafe.freeMemory(p.hashCode());
Run Code Online (Sandbox Code Playgroud)

似乎没有一些如何......

java jvm memory-management directmemory

4
推荐指数
1
解决办法
1852
查看次数

使用DMA访问高速串行端口

我在c#中使用serialport组件,效果很好!但问题是如何更快地处理高速(例如2 Mbps)数据传输.

正如我研究过的那样,我发现可以直接访问内存(使用像这个链接的 DMA ).谁能告诉我如何在我的应用程序中定义和使用它?

c# serial-port dma directmemory

4
推荐指数
1
解决办法
2059
查看次数

缓冲区与不安全区 - 外部JVM

我要求在GC无法控制的可用RAM中使用空格.我读了几篇同样的文章,介绍了两种方法.它们在以下代码中指定.

package com.directmemory;
Run Code Online (Sandbox Code Playgroud)

import java.lang.reflect.Field; import java.nio.ByteBuffer;

import sun.misc.Unsafe;

公共类DirectMemoryTest {

public static void main(String[] args) {

    //Approach 1
    ByteBuffer directByteBuffer = ByteBuffer.allocateDirect(8);
    directByteBuffer.putDouble(1.0);
    directByteBuffer.flip();
    System.out.println(directByteBuffer.getDouble());

    //Approach 2
    Unsafe unsafe = getUnsafe();
    long pointer = unsafe.allocateMemory(8);
    unsafe.putDouble(pointer, 2.0);
    unsafe.putDouble(pointer+8, 3.0);

    System.out.println(unsafe.getDouble(pointer));
    System.out.println(unsafe.getDouble(pointer+8));
    System.out.println(unsafe.getDouble(pointer+16));
}

public static Unsafe getUnsafe() {
    try {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        return (Unsafe) f.get(null);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

}

我有一些问题

1)为什么我应该注意代码中提到的方法1,因为根据我的理解,ByteBuffer.allocateDirect()不能返回一个存储容量大于2GB的缓冲区?因此,如果我的要求是存储3 GB的数据,我必须创建一个新的缓冲区并将数据存储在那里,这意味着除了存储数据之外,我还有额外的责任来识别相应的缓冲区(在'n列表中) 'buffers),它维护一个指向直接内存的指针.

2)不是方法2比方法1快一点,因为我不必首先找到缓冲区然后找到数据,我只需要一个对象字段的索引机制并使用getDouble/getInt方法并传递绝对值地址 ?

3)与PID相关的直接内存分配(关于堆内存吗?)?如果在一台机器上,我有2个java进程,在PID 1中的allocateMemory调用和PID 2给我永远不会交叉使用的内存块?

4)为什么最后一个sysout语句没有导致0.0?这个想法是每个double使用8个字节,所以我在allocateMemory返回的地址处存储1.0,表示地址= …

java directmemory

2
推荐指数
1
解决办法
1369
查看次数