张家港阿里网站建设/2023百度秒收录技术
17.4 Java堆空间内存分配
分配Java堆内存前,我们先通过两图来了解下C堆、Java堆、内核空间、native本地空间的关系。
1、从图17-1来看,Java堆的分配其实就是从Java进程运行时堆中选中一块内存区域来映射
2、从图17-2,可以看中各内存空间的关系,当然实际的内存区域比这个复杂的多,这里只是概括说明
图17-1
图17-2
17.4.1 genCollectedHeap.cpp
17.4.1.1 GenCollectedHeap::initialize
jint GenCollectedHeap::initialize() {// 这一步只是对c2编译器开通使用时,做一些参数赋值操作,这里就不展开讲CollectedHeap::pre_initialize();// 这里获取分代数_n_gens,就是2int i;_n_gens = gen_policy()->number_of_generations();// 保证2个值相等wordSize和HeapWordSize分别是在操作系统和Java堆中代表一个字word占用内存的大小,这两个值必然相同,否则出错guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize");// Java堆的对齐值,这个在`章节17.2.1.1`中有介绍size_t gen_alignment = Generation::GenGrain;// 获取分代对象数组,这个在`章节17.2.1.1`中有介绍,数组元素就2个,索引0元素表示年轻代,索引1元素表示老年代_gen_specs = gen_policy()->generations();// 分别遍历新生代和老年代,并设置各自分代的空间大小(初始值和最大值),同时确保内存对齐for (i = 0; i < _n_gens; i++) {_gen_specs[i]->align(gen_alignment);}// 下面才是给Java堆分配空间char* heap_address;size_t total_reserved = 0;int n_covered_regions = 0;ReservedSpace heap_rs;// 这是最外层Java堆的内存对齐值size_t heap_alignment = collector_policy()->heap_alignment();// 分配java堆内存,看`章节17.4.1.2`heap_address = allocate(heap_alignment, &total_reserved,&n_covered_regions, &heap_rs);if (!heap_rs.is_reserved()) {vm_shutdown_during_initialization("Could not reserve enough space for object heap");return JNI_ENOMEM;}// 将分配的Java堆内存,用 MemRegion 内存区域对象管理起来_reserved = MemRegion((HeapWord*)heap_rs.base(),(HeapWord*)(heap_rs.base() + heap_rs.size()));// 参数赋值_reserved.set_word_size(0);_reserved.set_start((HeapWord*)heap_rs.base()); // Java堆内存的首地址size_t actual_heap_size = heap_rs.size(); // Java堆内存大小// Java堆内存的限制地址,也就是不能超过这条线_reserved.set_end((HeapWord*)(heap_rs.base() + actual_heap_size)); // 接下来就是创建记忆集、卡表的过程,卡表和记忆集都是为了解决跨代引用的实现方案,后续讲GC时会有涉及_rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions);set_barrier_set(rem_set()->bs());_gch = this;for (i = 0; i < _n_gens; i++) {ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(), false, false);_gens[i] = _gen_specs[i]->init(this_rs, i, rem_set());heap_rs = heap_rs.last_part(_gen_specs[i]->max_size());}clear_incremental_collection_failed();#if INCLUDE_ALL_GCS// If we are running CMS, create the collector responsible// for collecting the CMS generations.if (collector_policy()->is_concurrent_mark_sweep_policy()) {bool success = create_cms_collector();if (!success) return JNI_ENOMEM;}
#endif // INCLUDE_ALL_GCSreturn JNI_OK;
}
17.4.1.2 GenCollectedHeap::allocate
char* GenCollectedHeap::allocate(size_t alignment,size_t* _total_reserved,int* _n_covered_regions,ReservedSpace* heap_rs){const char overflow_msg[] = "The size of the object heap + VM data exceeds ""the maximum representable size";// Now figure out the total size.size_t total_reserved = 0;int n_covered_regions = 0;const size_t pageSize = UseLargePages ?os::large_page_size() : os::vm_page_size();assert(alignment % pageSize == 0, "Must be");// 遍历_gen_specs,求得新生代和老年代的分配大小for (int i = 0; i < _n_gens; i++) {total_reserved += _gen_specs[i]->max_size();if (total_reserved < _gen_specs[i]->max_size()) {vm_exit_during_initialization(overflow_msg);}n_covered_regions += _gen_specs[i]->n_covered_regions(); // 最终为2}assert(total_reserved % alignment == 0,err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="SIZE_FORMAT, total_reserved, alignment));// Needed until the cardtable is fixed to have the right number// of covered regions.n_covered_regions += 2; // 再加2,就是4,也就是把堆最终分成4个区(新生代、S1、S2、老年代)*_total_reserved = total_reserved;*_n_covered_regions = n_covered_regions;// 分配内存,实现细节看`章节17.4.2`*heap_rs = Universe::reserve_heap(total_reserved, alignment);return heap_rs->base();
}
17.4.2 universe.cpp
17.4.2.1 Universe::reserve_heap
ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {assert(alignment <= Arguments::conservative_max_heap_alignment(),err_msg("actual alignment " SIZE_FORMAT " must be within maximum heap alignment " SIZE_FORMAT,alignment, Arguments::conservative_max_heap_alignment()));// 通过内存对齐,得到要分配的空间大小size_t total_reserved = align_size_up(heap_size, alignment);assert(!UseCompressedOops || (total_reserved <= (OopEncodingHeapMax - os::vm_page_size())),"heap size is too big for compressed oops");// 大页时考虑,本系列文章中不考虑大而情况,忽略bool use_large_pages = UseLargePages && is_size_aligned(alignment, os::large_page_size());assert(!UseLargePages|| UseParallelGC|| use_large_pages, "Wrong alignment to use large pages");// 取出Java堆的基址base的值,32位机器时,就是0,实现细节看`章节17.4.2.2`char* addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::UnscaledNarrowOop);// 创建一个ReservedHeapSpace对象,该对象就是用来保留连续内存地址范围空间的数据结构,实现细节看`章节17.4.3`ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages, addr);if (UseCompressedOops) {if (addr != NULL && !total_rs.is_reserved()) {// Failed to reserve at specified address - the requested memory// region is taken already, for example, by 'java' launcher.// Try again to reserver heap higher.addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::ZeroBasedNarrowOop);ReservedHeapSpace total_rs0(total_reserved, alignment,use_large_pages, addr);if (addr != NULL && !total_rs0.is_reserved()) {// Failed to reserve at specified address again - give up.addr = Universe::preferred_heap_base(total_reserved, alignment, Universe::HeapBasedNarrowOop);assert(addr == NULL, "");ReservedHeapSpace total_rs1(total_reserved, alignment,use_large_pages, addr);total_rs = total_rs1;} else {total_rs = total_rs0;}}}if (!total_rs.is_reserved()) {vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K));return total_rs;}if (UseCompressedOops) {// Universe::initialize_heap() will reset this to NULL if unscaled// or zero-based narrow oops are actually used.address base = (address)(total_rs.base() - os::vm_page_size());Universe::set_narrow_oop_base(base);}// 返回total_rsreturn total_rs;
}
17.4.2.2 Universe::preferred_heap_base
char* Universe::preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode) {assert(is_size_aligned((size_t)OopEncodingHeapMax, alignment), "Must be");assert(is_size_aligned((size_t)UnscaledOopHeapMax, alignment), "Must be");assert(is_size_aligned(heap_size, alignment), "Must be");// HeapBaseMinAddress 是操作系统明确设定的堆内存的最低地址限制,默认设置的是2*G,这里按alignment对齐,把HeapBaseMinAddress的值按alignment对齐后,作为堆内存的最低地址uintx heap_base_min_address_aligned = align_size_up(HeapBaseMinAddress, alignment);size_t base = 0;
#ifdef _LP64 // 下面是对64位机器及使用压缩指针时的实现,我们只讲32位的,这块逻辑略过if (UseCompressedOops) {assert(mode == UnscaledNarrowOop ||mode == ZeroBasedNarrowOop ||mode == HeapBasedNarrowOop, "mode is invalid");const size_t total_size = heap_size + heap_base_min_address_aligned;// Return specified base for the first request.if (!FLAG_IS_DEFAULT(HeapBaseMinAddress) && (mode == UnscaledNarrowOop)) {base = heap_base_min_address_aligned;// If the total size is small enough to allow UnscaledNarrowOop then// just use UnscaledNarrowOop.} else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) {if ((total_size <= UnscaledOopHeapMax) && (mode == UnscaledNarrowOop) &&(Universe::narrow_oop_shift() == 0)) {// Use 32-bits oops without encoding and// place heap's top on the 4Gb boundarybase = (UnscaledOopHeapMax - heap_size);} else {// Can't reserve with NarrowOopShift == 0Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);if (mode == UnscaledNarrowOop ||mode == ZeroBasedNarrowOop && total_size <= UnscaledOopHeapMax) {// Use zero based compressed oops with encoding and// place heap's top on the 32Gb boundary in case// total_size > 4Gb or failed to reserve below 4Gb.uint64_t heap_top = OopEncodingHeapMax;// For small heaps, save some space for compressed class pointer// space so it can be decoded with no base.if (UseCompressedClassPointers && !UseSharedSpaces &&OopEncodingHeapMax <= 32*G) {uint64_t class_space = align_size_up(CompressedClassSpaceSize, alignment);assert(is_size_aligned((size_t)OopEncodingHeapMax-class_space,alignment), "difference must be aligned too");uint64_t new_top = OopEncodingHeapMax-class_space;if (total_size <= new_top) {heap_top = new_top;}}// Align base to the adjusted top of the heapbase = heap_top - heap_size;}}} else {// UnscaledNarrowOop encoding didn't work, and no base was found for ZeroBasedOops or// HeapBasedNarrowOop encoding was requested. So, can't reserve below 32Gb.Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);}// Set narrow_oop_base and narrow_oop_use_implicit_null_checks// used in ReservedHeapSpace() constructors.// The final values will be set in initialize_heap() below.if ((base != 0) && ((base + heap_size) <= OopEncodingHeapMax)) {// Use zero based compressed oopsUniverse::set_narrow_oop_base(NULL);// Don't need guard page for implicit checks in indexed// addressing mode with zero based Compressed Oops.Universe::set_narrow_oop_use_implicit_null_checks(true);} else {// Set to a non-NULL value so the ReservedSpace ctor computes// the correct no-access prefix.// The final value will be set in initialize_heap() below.Universe::set_narrow_oop_base((address)UnscaledOopHeapMax);
#if defined(_WIN64) || defined(AIX)if (UseLargePages) {// Cannot allocate guard pages for implicit checks in indexed// addressing mode when large pages are specified on windows.Universe::set_narrow_oop_use_implicit_null_checks(false);}
#endif // _WIN64}}
#endifassert(is_ptr_aligned((char*)base, alignment), "Must be");// 最终返回base,在32位机器时,虚拟机就是返回0return (char*)base; // also return NULL (don't care) for 32-bit VM
}
17.4.3 virtualspace.cpp
17.4.3.1 ReservedHeapSpace::ReservedHeapSpace
ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment,bool large, char* requested_address) :/* 先调用父类构造函数*/ReservedSpace(size, alignment, large,requested_address,(UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&Universe::narrow_oop_use_implicit_null_checks()) ?lcm(os::vm_page_size(), alignment) : 0) {if (base() != NULL) {MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap);}// Only reserved space for the java heap should have a noaccess_prefix// if using compressed oops.protect_noaccess_prefix(size);
}
17.4.3.2 ReservedSpace::ReservedSpace
ReservedSpace::ReservedSpace(size_t size, size_t alignment,bool large,char* requested_address,const size_t noaccess_prefix) {initialize(size+noaccess_prefix, alignment, large, requested_address,noaccess_prefix, false);
}
17.4.3.3 ReservedSpace::initialize
入口函数: ReservedHeapSpace total_rs(total_reserved, alignment, use_large_pages, addr);
参数:
total_reserved 对应 size:空间大小
alignment 对应 alignment:内存对齐值
use_large_pages 对应 large:这里不考虑大页,就设置为false
addr 对应 requested_address:32位时,addr为0
noaccess_prefix 为 0
executable 为 false
void ReservedSpace::initialize(size_t size, size_t alignment, bool large,char* requested_address,const size_t noaccess_prefix,bool executable) {// 看源码得知,这里就是取page size(页大小),没什么逻辑const size_t granularity = os::vm_allocation_granularity();// 断言检验assert((size & (granularity - 1)) == 0,"size not aligned to os::vm_allocation_granularity()");assert((alignment & (granularity - 1)) == 0,"alignment not aligned to os::vm_allocation_granularity()");assert(alignment == 0 || is_power_of_2((intptr_t)alignment),"not a power of 2");// 取二者最大值对齐alignment = MAX2(alignment, (size_t)os::vm_page_size());// Assert that if noaccess_prefix is used, it is the same as alignment.assert(noaccess_prefix == 0 ||noaccess_prefix == alignment, "noaccess prefix wrong");_base = NULL;_size = 0;_special = false;_executable = executable;_alignment = 0;_noaccess_prefix = 0;if (size == 0) {return;}// 不存在大页,special 为 falsebool special = large && !os::can_commit_large_page_memory();char* base = NULL;// 32位机器时 requested_address == 0,这条线也不会走if (requested_address != 0) {requested_address -= noaccess_prefix; // adjust requested addressassert(requested_address != NULL, "huge noaccess prefix?");}// special为false,这个if不会走if (special) {base = os::reserve_memory_special(size, alignment, requested_address, executable);if (base != NULL) {if (failed_to_reserve_as_requested(base, requested_address, size, true)) {// OS ignored requested address. Try different address.return;}// Check alignment constraints.assert((uintptr_t) base % alignment == 0,err_msg("Large pages returned a non-aligned address, base: "PTR_FORMAT " alignment: " PTR_FORMAT,base, (void*)(uintptr_t)alignment));_special = true;} else {// failed; try to reserve regular memory belowif (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||!FLAG_IS_DEFAULT(LargePageSizeInBytes))) {if (PrintCompressedOopsMode) {tty->cr();tty->print_cr("Reserve regular memory without large pages.");}}}}if (base == NULL) {if (requested_address != 0) {base = os::attempt_reserve_memory_at(size, requested_address);if (failed_to_reserve_as_requested(base, requested_address, size, false)) {// OS ignored requested address. Try different address.base = NULL;}} else {// 这一步就是通过系统调用mmap映射一块size大小的内存,Java堆内存就是mmap映射出来的base = os::reserve_memory(size, NULL, alignment);}// 映射失败,直接退出函数,分配Java堆内存失败if (base == NULL) return;// 验证对齐,为啥要验证呢,因为base是mmap映射后返回的内存首地址,这个地址是os自己的规则选取的一个地址,不一定能按照alignment对齐,所以这一定要验证if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) {// base没有对齐,只能释放刚才mmap映射的内存,然后重试if (!os::release_memory(base, size)) fatal("os::release_memory failed");// 确保对齐size = align_size_up(size, alignment);// 再次mmap映射内存,返回的base同样有上面一样的不对齐问题,所以这个函数中包含了手动对齐操作,细节看`章节17.4.3.4`base = os::reserve_memory_aligned(size, alignment);if (requested_address != 0 &&failed_to_reserve_as_requested(base, requested_address, size, false)) {// As a result of the alignment constraints, the allocated base differs// from the requested address. Return back to the caller who can// take remedial action (like try again without a requested address).assert(_base == NULL, "should be");return;}}}// Done_base = base; // 最终拿到了Java堆的首地址_size = size; // 最终拿到了Java堆的大小_alignment = alignment; // 对齐值_noaccess_prefix = noaccess_prefix; // 0// 断言判断assert(noaccess_prefix == 0 ||noaccess_prefix == _alignment, "noaccess prefix wrong");assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base,"area must be distinguisable from marks for mark-sweep");assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size],"area must be distinguisable from marks for mark-sweep");
}
17.4.3.4 os_posix.cpp->os::reserve_memory_aligned
char* os::reserve_memory_aligned(size_t size, size_t alignment) {assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,"Alignment must be a multiple of allocation granularity (page size)");assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");size_t extra_size = size + alignment;assert(extra_size >= size, "overflow, size is too large to allow alignment");// mmap映射一块内存区域,返回首地址char* extra_base = os::reserve_memory(extra_size, NULL, alignment);if (extra_base == NULL) {return NULL;}// 手动对齐char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);// [ | | ]// ^ extra_base// ^ extra_base + begin_offset == aligned_base// extra_base + begin_offset + size ^// extra_base + extra_size ^// |<>| == begin_offset// end_offset == |<>|// 用对齐后的地址-mmap的首地址,得出与首地址的偏移值size_t begin_offset = aligned_base - extra_base;// 结束地址对齐后的偏移size_t end_offset = (extra_base + extra_size) - (aligned_base + size);// begin_offset > 0,表示确实有偏移,那就把extra_base到偏移的这部分释放掉,因为有新的首地址了if (begin_offset > 0) {os::release_memory(extra_base, begin_offset);}// end_offset > 0,表示确实有偏移,那就把end_offset偏移的这部分释放掉,因为有新的限制地址了if (end_offset > 0) {os::release_memory(extra_base + begin_offset + size, end_offset);}// 返回首地址return aligned_base;
}
相关文章:

Hotspot源码解析-第十七章-虚拟机万物创建(三)
17.4 Java堆空间内存分配 分配Java堆内存前,我们先通过两图来了解下C堆、Java堆、内核空间、native本地空间的关系。 1、从图17-1来看,Java堆的分配其实就是从Java进程运行时堆中选中一块内存区域来映射 2、从图17-2,可以看中各内存空间的…...

Spring MVC 的RequestMapping注解
RequestMapping注解 使用说明 作用:用于建立请求URL和处理请求方法之间的对应关系。 出现位置: 类上: 请求 URL的第一级访问目录。此处不写的话,就相当于应用的根目录。写的话需要以/开头。它出现的目的是为了使我们的 URL 可以…...

navicat for oracle
前言 Oracle中的概念并不是创建数据库,而是创建一个表空间,然后再创建一个用户,设置该用户的默认表空间为我们新创建的表空间,这些操作之后,便和你之前用过的mysql数据库创建完数据库一模一样了。 创建数据库 使用O…...

行业分享----dbaplus174期:美团基于Orchestrator的MySQL高可用实践
记录 MySQL高可用方案-MMM、MHA、MGR、PXC https://blog.csdn.net/jycjyc/article/details/119731980 美团数据库高可用架构的演进与设想 https://tech.meituan.com/2017/06/29/database-availability-architecture.html...

springboot集成钉钉通知
目录 1.通过自定义机器人方式发送群消息 1.1说明 1.2发送普通消息示例(采用加签方式) 1.3注意事项 2.通过企业内部应用发送钉钉消息 2.1说明 2.2示例 2.3注意 1.通过自定义机器人方式发送群消息 1.1说明 官网地址: 自定义机器人发送…...

直播预告丨看零售场,如何玩转 MaaS
今年,有一个被频繁提及的词是MaaS 这类工具正在帮助千行百业实现大模型落地产业 在零售场,特别是像京东这样拥有超高并发、超复杂协同的电商场内 也沉淀出了一套通用的AI基础设施——九数算法中台 从提升客户服务体验、平台效率出发,训练各…...

高创新!EI论文复现+改进:聚合温度调控策略的综合能源系统/微电网/虚拟电厂多目标优化调度程序代码!
程序考虑供热的热惯性,并根据室内供热效果进行柔性供热,发挥热温度负荷的“储能”能力;针对普适性参数的室内空调进行集群研究,深入剖析温度设定值调整导致负荷波动的机理,并提出一种新的温度调整方法,平抑…...

详解Matlab深度学习进行波形分割
🔗 运行环境:Matlab 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 🔐#### 防伪水印——左手の明天 ####🔐 💗 大家…...

如何在Windows 10/11的防火墙中禁止和允许某个应用程序,这里提供详细步骤
想阻止应用程序访问互联网吗?以下是如何通过简单的步骤阻止和允许Windows防火墙中的程序。 一般来说,大多数用户永远不需要担心应用程序访问互联网。然而,在某些情况下,你需要限制应用程序访问互联网。 例如,有问题…...

vivado 添加现有IP文件、生成IP
添加现有IP文件 作为从AMD IP目录添加和自定义IP的替代方案,您可以直接添加XCI或XCIX文件。此过程不同于从按以下方式编目: •XCI或XCIX文件可能是早期版本,也可能是相同或完全自定义的版本AMD IP目录中发现的类似IP。 •XCI或XCIX文件可能…...

C++右值引用,右值引用与const引用的区别
1.右值与左值 左值:可以取地址的、有名字的变量,有持久性;右值:一般是不可寻址的常量,或在表达式求值过程中创建的无名临时对象,短暂性的。 2.右值引用 C11新增了另一种引用——右值引用。这种引用可指向…...

启英泰伦推出「离线自然说」,离线语音交互随意说,不需记忆词条
离线语音识别是指不需要依赖网络,在本地设备实现语音识别的过程,通常以端侧AI语音芯片作为载体来进行数据的采集、计算和决策。但是语音芯片的存储空间有限,通过传统的语音算法技术,最多也只能存储数百条词条,导致用户…...

Vulnhub-DC1
前言 一个比较简单的实战靶场,官方要求是找到/root下的flag,所以直接提权即可。但对于学习和训练来说还是太简略了,在打靶场的时候还是全面一些较好。 本次靶场实战涉及信息收集、漏洞查找与利用、getshell、数据库渗透、密码破解、linux提…...

【c++笔记】总结!c++与c语言的不同之处
(Θ3Θ) hi~ 众所周知\(^o^)/~,c语言和c联系密切,又相互区别,本篇文章主要介绍c与c语言的区别与联系以及一些简单的不同点的运用,很适合刚接触c的朋友,一起来瞧瞧看吧~~ 目录 一、文章内容梗概 二、概念…...

大模型PEFT技术原理(一):BitFit、Prefix Tuning、Prompt Tuning
随着预训练模型的参数越来越大,尤其是175B参数大小的GPT3发布以来,让很多中小公司和个人研究员对于大模型的全量微调望而却步,近年来研究者们提出了各种各样的参数高效迁移学习方法(Parameter-efficient Transfer Learning&#x…...

VMware vSphere运维管理手册
适用版本:VMware vSphere 7.0 VMware vSphere 是 VMware 的虚拟化平台,可将数据中心转换为包括 CPU、存储和网络资源的聚合计算基础架构。vSphere 将这些基础架构作为一个统一的运行环境进行管理,并为您提供工具来管理加入该环境的数据中心。 
学习笔记-mysql-各种函数的基本使用
1. 聚合函数 count , sum , min , max ,avg , group_concat() -- 将所有员工的名字合并成一行 select group_concat(emp_name) from emp; -- 指定分隔符合并 select department,group_concat(emp_name separator ; ) from emp group by department; -- 指定排序方式和分隔…...

DD小桔高级数分 2面挂
偏业务分析一点,注重AB实验在实际业务中的操作、业务方交流方式 一面|同事面 中规中矩,面试内容偏简单,不知道是不是因为晚8点面试的原因项目没有进行深究 自我介绍项目介绍1.你在实际项目中是怎么设计AB实验2.你在实际业务场景中是怎么判…...

居中面试问题
前端常问居中面试问题 css文本居中 文本水平居中 <div class"father"><div class"child"><div> <div>子类元素为行内元素,则给父类元素定义text-align:center 如果子元素是块元素,则给子元素定义margin&…...
网页设计-用户体验
Use Cases (用例) 用例是用户如何在网站上执行任务的书面描述,从用户的角度描述了系统响应请求时的行为。每个用例都是用户实现目标的一系列简单的步骤。简言之,用例是一种用于描述系统如何满足用户需求的方法。 用例的好处 1. 明确需求: Use…...

docker应用:vocechat
简介:VoceChat是一款超轻量级的Rust聊天应用程序、API和SDK,优先考虑私人托管。使用VoceChat建立您自己的聊天功能!作为一款非常好用的通讯应用程序,它可以让你与朋友、家人和同事进行即时消息聊天,支持图片视频的分享…...

linux 02 vmware的快照,文件管理
01.快照 使用快照: 同时的快照管理器: 如果想要返回快照,选择要选择的快照,跳转 02. 文件管理: cd 修改当前路径 02.touch 创建文件 03. mkdir 创建文件夹 mkdir -p 文件夹 (创建之前没有的上级文件…...

项目架构之Zabbix部署
1 项目架构 1.1 项目架构的组成 业务架构:客户端 → 防火墙 → 负载均衡(四层、七层) → web缓存/应用 → 业务逻辑(动态应用) → 数据缓存 → 数据持久层 运维架构:运维客户端 → 跳板机/堡垒机&#x…...

RocketMQ源码阅读-Message消息存储
RocketMQ源码阅读-Message消息存储 1. CommitLog的作用2. CommitLog 存储消息3. 时序图4. 小结 在Broker消息接收一篇中,分析到Broker接收到消息,最终会调用CommitLong#putMessage方法存储消息。 本篇来分析CommitLong#putMessage存储消息的流程。 1. C…...

《C语言学习》---郝斌版---笔记
简介 学习计算机,离不开C语言的学习,而C语言学习过程中的视频课教程,目前来说,如果郝斌老师的C语言排第二,没有人敢排第一 郝斌老师的C语言教程,通俗易懂,引人发思,特别适合新手入门…...

Python(32):字符串转换成列表或元组,列表转换成字典小例子
1、python 两个列表转换成字典 字符串转换成列表 列表转换成字典 column "ID,aes,sm4,sm4_a,email,phone,ssn,military,passport,intelssn,intelpassport,intelmilitary,intelganghui,inteltaitonei,credit_card_short,credit_card_long,job,sm4_cbc,sm4_a_cbc" …...

CentOS 7 安装私有平台OpenNebula
目录 一、配置yum源 二、配置数据库MySQL 2.1 安装MySQL 2.2 修改MySQL密码 2.3 创建项目用户和库 三、安装配置前端包 四、设置oneadmin账号密码 五、验证安装 5.1 命令行验证安装 5.2 数据存放位置 5.3 端口介绍 5.4 命令介绍 六、访问 6.1 设置语言 6.2 创建主…...

(aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
1. 背景介绍 在先前的博客文章中,我们已经搭建了一个基于SRS的流媒体服务器。现在,我们希望通过Web接口来控制这个服务器的行为,特别是对于正在进行的 RTSP 转码任务的管理。这将使我们能够在不停止整个服务器的情况下,动态地启动…...

基于STM32微控制器的四轮智能小车控制系统设计
标题:基于STM32微控制器的四轮智能小车控制系统设计与实现 摘要: 本文针对移动机器人领域的应用需求,详细介绍了基于STM32系列单片机(以STM32F103C8T6为例)为核心的四轮小车控制系统的设计和实现过程。该系统集成了电…...

JPA的复杂查询包括一对多多对一和多对多的查询
1. 多表关联查询和排序 假设我们有两个实体类:Customer和Order,它们之间是一对多的关系,即一个客户可以有多个订单。我们想要查询某个客户的所有订单,并按订单金额进行降序排序。 Entity Table(name "customers") pu…...