当前位置: 首页 > news >正文

甘肃庆阳疫情最新情况徐州自动seo

甘肃庆阳疫情最新情况,徐州自动seo,智通人才网招聘网东莞官网,手机app可以做网站吗文章目录1. 什么是直接内存2. 直接内存分配源码分析3. 使用直接内存的优缺点:1. 什么是直接内存 直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,某些情况下这部分内…

文章目录

  • 1. 什么是直接内存
  • 2. 直接内存分配源码分析
  • 3. 使用直接内存的优缺点:

1. 什么是直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,某些情况下这部分内存也会被频繁地使用,而且也可能导致OutOfMemoryError异常出现。

Java里用DirectByteBuffer可以分配一块直接内存(堆外内存),元空间对应的内存也叫作直接内存,它们对应的都是机器的物理内存。

在这里插入图片描述

package com.test;import java.nio.ByteBuffer;public class DirectMemoryTest {public static void heapAccess() {long startTime = System.currentTimeMillis();//分配堆内存ByteBuffer buffer = ByteBuffer.allocate(1000);for (int i = 0; i < 100000; i++) {for (int j = 0; j < 200; j++) {buffer.putInt(j);}buffer.flip();for (int j = 0; j < 200; j++) {buffer.getInt();}buffer.clear();}long endTime = System.currentTimeMillis();System.out.println("堆内存访问:" + (endTime - startTime) + "ms");}public static void directAccess() {long startTime = System.currentTimeMillis();//分配直接内存ByteBuffer buffer = ByteBuffer.allocateDirect(1000);for (int i = 0; i < 100000; i++) {for (int j = 0; j < 200; j++) {buffer.putInt(j);}buffer.flip();for (int j = 0; j < 200; j++) {buffer.getInt();}buffer.clear();}long endTime = System.currentTimeMillis();System.out.println("直接内存访问:" + (endTime - startTime) + "ms");}public static void heapAllocate() {long startTime = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {ByteBuffer.allocate(100);}long endTime = System.currentTimeMillis();System.out.println("堆内存申请:" + (endTime - startTime) + "ms");}public static void directAllocate() {long startTime = System.currentTimeMillis();for (int i = 0; i < 100000; i++) {ByteBuffer.allocateDirect(100);}long endTime = System.currentTimeMillis();System.out.println("直接内存申请:" + (endTime - startTime) + "ms");}public static void main(String args[]) {//访问速度进行对比for (int i = 0; i < 10; i++) {heapAccess();directAccess();}System.out.println("----------");//申请速度进行对比for (int i = 0; i < 10; i++) {heapAllocate();directAllocate();}}
}

在这里插入图片描述
从程序运行结果看出直接内存申请较慢,但访问效率高。在java虚拟机实现上,本地IO一般会直接操作直接内存(直接内存=>系统调用=>硬盘/网卡),而非直接内存则需要二次拷贝(堆内存=>直接内存=>系统调用=>硬盘/网卡)。

2. 直接内存分配源码分析

    public static ByteBuffer allocateDirect(int capacity) {return new DirectByteBuffer(capacity);}DirectByteBuffer(int cap) {                   super(-1, 0, cap, cap);boolean pa = VM.isDirectMemoryPageAligned();int ps = Bits.pageSize();long size = Math.max(1L, (long)cap + (pa ? ps : 0));//判断是否有足够的直接内存空间分配,可通过‐XX:MaxDirectMemorySize=<size>参数指定直接内存最大可分配空间,如果不指定默认为最大堆内存大小,//在分配直接内存时如果发现空间不够会显示调用System.gc()触发一次full gc回收掉一部分无用的直接内存的引用对象,同时直接内存也会被释放掉//如果释放完分配空间还是不够会抛出异常java.lang.OutOfMemoryErrorBits.reserveMemory(size, cap);long base = 0;try {// 调用unsafe本地方法分配直接内存base = unsafe.allocateMemory(size);} catch (OutOfMemoryError x) {// 分配失败,释放内存Bits.unreserveMemory(size, cap);throw x;}unsafe.setMemory(base, size, (byte) 0);if (pa && (base % ps != 0)) {// Round up to page boundaryaddress = base + ps - (base & (ps - 1));} else {address = base;}// 使用Cleaner机制注册内存回收处理函数,当直接内存引用对象被GC清理掉时,// 会提前调用这里注册的释放直接内存的Deallocator线程对象的run方法cleaner = Cleaner.create(this, new Deallocator(base, size, cap));att = null;}public final class Unsafe {// 申请一块本地内存。内存空间是未初始化的,其内容是无法预期的。// 使用freeMemory释放内存,使用reallocateMemory修改内存大小public native long allocateMemory(long bytes);}//jvm源码 openjdk8/hotspot/src/share/vm/prims/unsafe.cppUNSAFE_ENTRY(jlong, Unsafe_AllocateMemory(JNIEnv *env, jobject unsafe, jlong size))UnsafeWrapper("Unsafe_AllocateMemory");size_t sz = (size_t)size;if (sz != (julong)size || size < 0) {THROW_0(vmSymbols::java_lang_IllegalArgumentException());}if (sz == 0) {return 0;}sz = round_to(sz, HeapWordSize);// 调用os::malloc申请内存,内部使用malloc这个C标准库的函数申请内存void* x = os::malloc(sz, mtInternal);if (x == NULL) {THROW_0(vmSymbols::java_lang_OutOfMemoryError());}//Copy::fill_to_words((HeapWord*)x, sz / HeapWordSize);return addr_to_java(x);UNSAFE_END

3. 使用直接内存的优缺点:

优点:

  • 不占用堆内存空间,减少了发生GC的可能
  • java虚拟机实现上,本地IO会直接操作直接内存(直接内存=>系统调用=>硬盘/网卡),而非直接内存则需要二次拷贝(堆内存=>直接内存=>系统调用=>硬盘/网卡)

缺点:

  • 初始分配较慢
  • 没有JVM直接帮助管理内存,容易发生内存溢出。为了避免一直没有FULL GC,最终导致直接内存把物理内存耗完。我们可以指定直接内存的最大值,通过-XX:MaxDirectMemorySize来指定,当达到阈值的时候,调用system.gc来进行一次FULL GC,间接把那些没有被使用的直接内存回收掉。
http://www.lbrq.cn/news/2702881.html

相关文章:

  • wordpress开发的网站长沙seo优化
  • 合肥企业快速建站1688网站
  • 做网站的开发语言seo推广优化平台
  • 个人备案的网站做企业站军事新闻头条
  • 织梦做网站竞价广告点击软件
  • 企业网站及公众号建设方案常德网站建设制作
  • html网站开发 工具短视频剪辑培训班速成
  • 钓鱼网站怎么制作视频百度广告点击软件源码
  • 2017设计工作室做网站站长工具seo优化
  • 网站建设 提案 框架互联网营销师含金量
  • 跟老外做网站人民日报客户端
  • 电商网站建设建议域名注册网站查询
  • 路南网站建设网络推广产品公司
  • 房产网站系统源码上海百度推广平台
  • 凡科删除建设的网站自助建站免费建站平台
  • 建设一个公司网站需要多少钱网站运营推广方案
  • asp.net 网站管理系统百度地图推广
  • 那个可以做棋牌网站seo关键词教程
  • 注册公司需要的网站建设百度网站收录链接提交
  • 广州做网络服装的网站建设关键词的分类和优化
  • 网站友情链接怎么做国内高清视频素材网站推荐
  • 网站建设 地址 昌乐站长工具介绍
  • 宁夏网站建设一条龙计算机培训机构
  • 杭州网站建设品牌推广一款app的营销方案
  • 遵义网站搭建公司哪家好网站建设选亿企网络
  • 巴中网站建设培训班百度分析
  • 网站建设与管理自简历网站建设平台
  • 提升网站权重禁止搜索引擎收录的方法
  • 美食网站要怎么做南京seo
  • 国际贸易英文网站优化网站的步骤
  • Python函数篇:从零到精通
  • 力扣top100(day01-05)--矩阵
  • cuda排序算法--双调排序(Bitonic_Sort)
  • 动态规划----1.爬楼梯
  • CSS预处理器之Sass全面解析与实战指南
  • 【openEuler构建测试环境或部署嵌入式系统】openEuler生态扩容新路径:内网穿透工具cpolar助力多场景落地