• 关于

    引用计数

    的搜索结果

回答

内存管理机制: 引用计数、垃圾回收、内存池 引用计数:引用计数是一种非常高效的内存管理手段,当一个Python对象被引用时其引用计数增加1, 当其不再被一个变量引用时则计数减1,当引用计数等于0时对象被删除。弱引用不会增加引用计数 垃圾回收: 1.引用计数 引用计数也是一种垃圾收集机制,而且也是一种最直观、最简单的垃圾收集技术。当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了。比如某个新建对象,它被分配给某个引用,对象的引用计数变为1,如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。不过如果出现循环引用的话,引用计数机制就不再起有效的作用了。 2.标记清除 调优手段 1.手动垃圾回收 2.调高垃圾回收阈值 3.避免循环引用

珍宝珠 2019-12-02 03:12:47 0 浏览量 回答数 0

回答

关于Python中的内存释放问题首先就不得不提到Python解释器在何种情况下会释放变量的内存。Python引用了内存计数这一简单的计数来控制。下面是引用计数的知识:1) 增加引用计数 当对象被创建并(将其引用)赋值给变量时,该对象的引用计数被设置为1。对象的引用计数增加的情况:对象被创建:x = 3.14另外的别名被创建:y = x被作为参数传递给函数(新的本地引用):foobar(x)成为容器对象的一个元素:myList = [123, x, 'xyz']2) 减少引用计数 对象的引用计数减少的情况:一个本地引用离开了其作用范围。如foobar()函数结束时对象的别名被显式销毁:del y对象的一个别名被赋值给其他对象:x = 123对象被从一个窗口对象中移除:myList.remove(x)窗口对象本身被销毁:del myList3) del语句 Del语句会删除对象的一个引用,它的语法如下:del obj[, obj2[, ...objN]]例如,在上例中执行del y会产生两个结果:从现在的名称空间中删除yx的引用计数减1import sysx = 3.14print("原始引用值:", sys.getrefcount(x))y = xprint("被y引用后:", sys.getrefcount(x))x = 4.0print("重新赋值后:", sys.getrefcount(x))del yprint("删除y引用后:", sys.getrefcount(x))原始引用值: 3被y引用后: 4重新赋值后: 3删除y引用后: 3当一个变量的引用计数为0的时候,就会被解释器回收。当然在交互模式下,内存不会马上释放,重新启动解释器就会释放了。

ylrf1212 2019-12-02 01:08:33 0 浏览量 回答数 0

回答

引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到环的存在。 首先需要声明,至少主流的Java虚拟机里面都没有选用引用计数算法来管理内存。 什么是引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值加1;当引用失效时,计数器值减1.任何时刻计数器值为0的对象就是不可能再被使用的。那为什么主流的Java虚拟机里面都没有选用这种算法呢?其中最主要的原因是它很难解决对象之间相互循环引用的问题。

星尘linger 2020-04-13 09:06:58 0 浏览量 回答数 0

回答

通过以下三个方法 retain 增加引用计数 release 降低引用计数,引用计数为0的时候,释放对象。 autorelease 在当前的auto release pool结束后,降低引用计数

1745426477080495 2019-12-02 03:15:01 0 浏览量 回答数 0

问题

. jvm 垃圾回:引用计数和可达性分析

Atom 2020-04-25 16:56:36 10 浏览量 回答数 1

回答

垃圾收集GC(Garbage Collection)是Java语言的核心技术之一, 在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给了JVM来处理。针对GC我们这篇文章提出以下几个问题,GC中判定为垃圾的标准,标记垃圾的算法以及回收垃圾的算法。 什么样的对象才是垃圾? 这个问题其实很简单,对于Java对象来讲,如果说这个对象没有被其他对象所引用该对象就是无用的,此对象就被称为垃圾,其占用的内存也就要被销毁。那么自然而然的就引出了我们的第二个问题,判断对象为垃圾的算法都有哪些? 标记垃圾的算法 Java中标记垃圾的算法主要有两种, 引用计数法和可达性分析算法。我们首先来介绍引用计数法。 引用计数法 引用计数法就是给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的,可以当做垃圾收集。这种方法实现起来很简单而且优缺点都很明显。 优点 执行效率高,程序执行受影响较小 缺点 无法检测出循环引用的情况,导致内存泄露

苍霞学子 2020-03-26 09:52:48 0 浏览量 回答数 0

回答

垃圾收集器在做垃圾回收的时候,首先需要判定的就是哪些内存是需要被回收的,哪些对象是「存活」的,是不可以被回收的;哪些对象已经「死掉」了,需要被回收。 一般有两种方法来判断: 引用计数器法:为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题;可达性分析算法:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。 原文链接:https://thinkwon.blog.csdn.net/article/details/104390752

剑曼红尘 2020-03-11 13:17:44 0 浏览量 回答数 0

回答

@property(nonatomic, retain)标明该属性在使用其set方法时会自动retain一次。 self.leftView = [[UIView alloc] initWithFrame:...];这条语句,alloc使其引用计数+1,同时调用leftView的set方法,引用计数再+1,引用计数一共加了2次,而实际上我们想要的效果是引用计数只加1次,所以有内存泄露。 正确的写法应该是: UIView *myView = [[UIView alloc] initWithFrame:...]; self.leftView = myView; [myView release]; 这样Analyze时就不会提示内存泄露。

a123456678 2019-12-02 03:12:59 0 浏览量 回答数 0

回答

看回答,回了一堆百度文。 简单点,就是一个引用计数器。当一个对象被引用时,计数器+1. 当没有引用时计数器为0.此时自动进行垃圾回收。 这样概括好一点吧。

游客aasf2nc2ujisi 2019-12-02 03:09:40 0 浏览量 回答数 0

回答

1.所有实例都没有活动线程访问。 2.没有被其他任何实例访问的循环引用实例。 3.Java 中有不同的引用类型。判断实例是否符合垃圾收集的条件都依赖于它的引用类型。 要判断怎样的对象是没用的对象。这里有2种方法: 1.采用标记计数的方法: 给内存中的对象给打上标记,对象被引用一次,计数就加1,引用被释放了,计数就减一,当这个计数为0的时候,这个对象就可以被回收了。当然,这也就引发了一个问题:循环引用的对象是无法被识别出来并且被回收的。所以就有了第二种方法: 2.采用根搜索算法: 从一个根出发,搜索所有的可达对象,这样剩下的那些对象就是需要被回收的

游客bnlxddh3fwntw 2020-04-10 14:16:47 0 浏览量 回答数 0

回答

引用相当于指针。多个变量引用同一个对象实例,通过其中一个去修改它,结果会作用到所有引用变量上,因为它们其实都指向同一个对象。js内部会维护一个引用计数,如果没有变量这个对象(引用计数为0),也就代表这个对象没用了,可以被垃圾回收。

小旋风柴进 2019-12-02 02:30:04 0 浏览量 回答数 0

回答

引用计数法 通过计数,判断是否有人在引用,当数值不在,就代表要回收 引用链法 基本相同道理

huc_逆天 2019-12-02 03:15:35 0 浏览量 回答数 0

问题

Java JVM 引用计数法是什么?

小天使爱美 2020-04-12 21:46:15 4 浏览量 回答数 1

回答

@SimpleFast 请帮忙看看 你看你的 PublishHandler类继承的是不是simple开头的一个类,这个类会自动的调用 release方法,所以你再进行调用的话,会导致该异常出现回复 @兮风古道:两位大哥说的对..我看了SimpleInBoundChannel的文档,确实是这样的.我想知道为什么要这样设计呢?直接让我们自己实现的子类用完了自己释放不好吗?回复 @plugin:你要想自己管理引用计数,就不要继承SimpleInBoundChannelnetty的官方资料上对于这种引用计数的对象的管理,有两个原则1当一个组件要把引用计数对象传给另一组件时,该对象何时销毁由另一组件决定2如果一个组件内部的引用计数对象不会再被其他组件访问了,则销毁他。对于我这里的问题,我不明白为什么要SimpleInBoundChannel类里去release它,而不是让我自己的子类去做

爱吃鱼的程序员 2020-06-10 14:33:01 0 浏览量 回答数 0

回答

block按照内存分布,分三种类型:全局内存中的block、栈内存中的block、堆内存中的block。 在MRC和ARC下block的分布情况不一样 MRC下: 当block内部引用全局变量或者不引用任何外部变量时,该block是在全局内存中的。 当block内部引用了外部的非全局变量的时候,该block是在栈内存中的。 当栈中的block进行copy操作时,会将block拷贝到堆内存中。 通过__block修饰的变量,不会对其应用计数+1,不会造成循环引用。 ARC下: 当block内部引用全局变量或者不引用任何外部变量时,该block是在全局内存中的。 当block内部引用了外部的非全局变量的时候,该block是在堆内存中的。 也就是说,ARC下只存在全局block和堆block。 通过__block修饰的变量,在block内部依然会对其引用计数+1,可能会造成循环引用。 通过__weak修饰的变量,在block内部不会对其引用计数+1,不会造成循环引用。 参考这篇文章

montos 2020-04-13 20:55:01 0 浏览量 回答数 0

回答

1)引用计数机制:Python内部使用引用计数,来保持追踪内存中的对象。 2)垃圾回收机制:当一个对象的引用计数归零时,它将被垃圾收集机制处理掉;                                循环垃圾回收器,确保释放循环引用对象。 3).内存池机制: Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统: Pymalloc机制:为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。

天枢2020 2020-04-26 15:58:29 0 浏览量 回答数 0

回答

引用计数netty中使用引用计数机制来管理资源,当一个实现ReferenceCounted的对象实例化时,引用计数置1.客户代码中需要保持一个该对象的引用时需要调用接口的retain方法将计数增1.对象使用完毕时调用release将计数减1.当引用计数变为0时,对象将释放所持有的底层资源或将资源返回资源池. 内存泄露按上述规则使用Direct和Pooled的ByteBuf尤其重要.对于DirectBuf,其内存不受VM垃圾回收控制只有在调用release导致计数为0时才会主动释放内存,而PooledByteBuf只有在release后才能被回收到池中以循环利用.如果客户代码没有按引用计数规则使用这两种对象,将会导致内存泄露. 内存使用跟踪在netty.io.util包中含有如下两个类ResourceLeak 用于跟踪内存泄露ResourceLeakDetector 内存泄露检测工具在io.netty.buffer.AbstractByteBufAllocator类中有如下代码 [java] view plaincopy在CODE上查看代码片派生到我的代码片 //装饰器模式,用SimpleLeakAwareByteBuf或AdvancedLeakAwareByteBuf来包装原始的ByteBuf //两个包装类均通过调用ResourceLeak的record方法来记录ByteBuf的方法调用堆栈,区别在于后者比前者记录更多的内容 protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) { ResourceLeak leak; //根据设置的Level来选择使用何种包装器 switch (ResourceLeakDetector.getLevel()) { case SIMPLE: //创建用于跟踪和表示内容泄露的ResourcLeak对象 leak = AbstractByteBuf.leakDetector.open(buf); if (leak != null) { //只在ByteBuf.order方法中调用ResourceLeak.record buf = new SimpleLeakAwareByteBuf(buf, leak); } break; case ADVANCED: case PARANOID: leak = AbstractByteBuf.leakDetector.open(buf); if (leak != null) { //在ByteBuf几乎所有方法中调用ResourceLeak.record buf = new AdvancedLeakAwareByteBuf(buf, leak); } break; } return buf; } 下图展示了该方法被调用的时机.可见Netty只对PooledByteBuf和DirectByteBuf监控内存泄露. 内存泄露检测 下面观察上述代码中的AbstractByteBuf.leakDetector.open(buf); 实现代码如下[java] view plaincopy在CODE上查看代码片派生到我的代码片 //创建用于跟踪和表示内容泄露的ResourcLeak对象 public ResourceLeak open(T obj) { Level level = ResourceLeakDetector.level; if (level == Level.DISABLED) {//禁用内存跟踪 return null; } if (level.ordinal() < Level.PARANOID.ordinal()) { //如果监控级别低于PARANOID,在一定的采样频率下报告内存泄露 if (leakCheckCnt ++ % samplingInterval == 0) { reportLeak(level); return new DefaultResourceLeak(obj); } else { return null; } } else { //每次需要分配 ByteBuf 时,报告内存泄露情况 reportLeak(level); return new DefaultResourceLeak(obj); } } 其中reportLeak方法中完成对内存泄露的检测和报告,如下面代码所示. [java] view plaincopy在CODE上查看代码片派生到我的代码片 private void reportLeak(Level level) { //...... // 报告生成了太多的活跃资源 int samplingInterval = level == Level.PARANOID? 1 : this.samplingInterval; if (active * samplingInterval > maxActive && loggedTooManyActive.compareAndSet(false, true)) { logger.error("LEAK: You are creating too many " + resourceType + " instances. " + resourceType + " is a shared resource that must be reused across the JVM," + "so that only a few instances are created."); } // 检测并报告之前发生的内存泄露 for (;;) { @SuppressWarnings("unchecked") //检查引用队列(为什么通过检查该队列,可以判断是否存在内存泄露) DefaultResourceLeak ref = (DefaultResourceLeak) refQueue.poll(); if (ref == null) {//队列为空,没有未报告的内存泄露或者从未发生内存泄露 break; } //清理引用 ref.clear(); if (!ref.close()) { continue; } //通过错误日志打印资源的方法调用记录,并将其保存在reportedLeaks中 String records = ref.toString(); if (reportedLeaks.putIfAbsent(records, Boolean.TRUE) == null) { if (records.isEmpty()) { logger.error("LEAK: {}.release() was not called before it's garbage-collected. " + "Enable advanced leak reporting to find out where the leak occurred. " + "To enable advanced leak reporting, " + "specify the JVM option '-D{}={}' or call {}.setLevel()", resourceType, PROP_LEVEL, Level.ADVANCED.name().toLowerCase(), simpleClassName(this)); } else { logger.error( "LEAK: {}.release() was not called before it's garbage-collected.{}", resourceType, records); } } } } 综合上面的三段代码,可以看出, Netty 在分配新 ByteBuf 时进行内存泄露检测和报告.DefaultResourceLeak的声明如下 [java] view plaincopy在CODE上查看代码片派生到我的代码片 private final class DefaultResourceLeak extends PhantomReference //...... public DefaultResourceLeak(Object referent) { //使用一个静态的引用队列(refQueue)初始化 //refQueue是ResourceLeakDecetor的成员变量并由其初始化 super(referent, referent != null? refQueue : null); //...... } //...... } 可见DefaultResourceLeak是个”虚”引用类型,有别于常见的普通的”强”引用,虚引用完全不影响目标对象的垃圾回收,但是会在目标对象被VM垃圾回收时被加入到引用队列中.在正常情况下ResourceLeak对象会所监控的资源的引用计数为0时被清理掉(不在被加入引用队列),所以一旦资源的引用计数失常,ResourceLeak对象会被加入到引用队列.例如没有成对调用ByteBuf的retain和relaease方法,导致ByteBuf没有被正常释放(对于DirectByteBuf没有及时释放内存,对于PooledByteBuf没有返回Pool),当引用队列中存在元素时意味着程序中有内存泄露发生.ResourceLeakDetector通过检查引用队列来判断是否有内存泄露,并报告跟踪情况.

hiekay 2019-12-02 01:42:59 0 浏览量 回答数 0

问题

迁移没有遵守命名规范的代码库

爵霸 2019-12-01 19:32:16 870 浏览量 回答数 1

回答

引用计数法、可达性算法、虚拟机栈中引用的对象、方法区类静态属性引用的对象、方法区常量池引用的对象、本地方法栈 JNI 引用的对象

游客pklijor6gytpx 2019-12-02 03:14:21 0 浏览量 回答数 0

回答

首先要理解fork的一个特性: 父进程的所有打开文件描述符都会被复制到子进程中,父、子进程的每个相同的打开描述符共享一个文件表项。如下图(摘自APUE)所示。另外,在文件表中还有一项:打开文件引用计数,引用这个文件对象的描述符数(dup和fork都会增加这个计数,第一次open会使此计数为1,close会减小此计数,为0时销毁文件对象)。所以在程序的运行过程中,不管是父进程还是子进程先close(fd)或fclose(fp),该文件表依然存在并没有被销毁,只有当文件表中的打开文件引用计数为0时才会销毁这个文件表对象。题1中的I/O都是通过Linux系统调用来完成的,这些函数也常被称为不带缓冲的I/O(unbuffered I/O)。所以每一次调用都会立即写入文件中。而对于题2中的标准I/O库函数来说,都是带缓冲的,文件一般都是全缓冲,也就是说一定要把缓冲区填满才能进行实际的I/O操作。在执行语句fprintf(fp, "%s", msg1);时,由于没有填满缓冲区而实际的I/O操作并未完成。这时却调用了fork函数,这个函数同时也会把该缓冲区复制一份给子进程,这样在父、子进程中就各有一份msg1,当缓冲区填满后就会被刷新以进行实际的I/O操作(写入文件)。int fflush ( FILE * stream );函数能够提供手动进行刷新缓冲区,楼主可以试试在将msg1写入文件这条语句后面加上fflush(fp);则得出的结果将会和题1一样。

a123456678 2019-12-02 02:54:13 0 浏览量 回答数 0

回答

python增圾回收是采用引用计数的方法。引用为0回收。 del释放对角引用。

游客aasf2nc2ujisi 2019-12-02 03:11:10 0 浏览量 回答数 0

回答

单步运行到getBytes()会报告IllegalReferenceCountException异常。###### ByteBuf使用了引用计数,缺省下读取一次之后refCnt就会减到0,再读就出现异常了。 如果使用retain()可以增加引用计数,可以多读一次;相反,release()则减一次,可能还没有读就不能再读了。

kun坤 2020-06-07 16:32:15 0 浏览量 回答数 0

回答

你那个name属于现在一个新的对象,它指向一块内存,引用计数的原理就是去标记一块内存有几个对象指向它,当没对象指向他的时候引用计数等于0,然后调用dealloc方法,所以当你的name申请的时候count = 1,这时name指向这块内存,然后你又把这块内存的地址给了_name,此时_name也指向了这块内存,所以这块内存的count应该加1等于2,所以通过retain让他加到2

爵霸 2019-12-02 02:05:21 0 浏览量 回答数 0

回答

Python的内存管理机制可以从三个方面: 1.垃圾回收--运行时 2.引用计数--对象的引用计数 3.内存池机制--金字塔型 建议参考Python官网对不同变量,这三方面如何进行操作和管理的。 Python调优手段主要依赖于你自己本身的业务是IO密集型还是CPU密集型,针对不同的也无需求再确定优化。可以使用cprofile或者line_Profile等工具来分析和调优。

brian.lv 2019-12-02 03:12:56 0 浏览量 回答数 0

回答

内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。 有__del__()函数的对象间的循环引用是导致内存泄露的主凶。不使用一个对象时使用: del object 来删除一个对象的引用计数就可以有效防止内存泄露问题。 通过Python扩展模块gc 来查看不能回收的对象的详细信息。 可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为0来判断是否内存泄露

珍宝珠 2019-12-02 03:12:47 0 浏览量 回答数 0

回答

weak:其实是一个hash表结构,其中的key是所指对象的地址,value是weak的指针数组,weak表示的是弱引用,不会对对象引用计数+1,当引用的对象被释放的时候,其值被自动设置为nil,一般用于解决循环引用的。 weak的实现原理 1、初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。 2、添加引用时:objc_initWeak函数会调用 objc_storeWeak() 函数, objc_storeWeak() 的作用是更新指针指向,创建对应的弱引用表。 3、释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。 SideTable的结构如下: struct SideTable { // 保证原子操作的自旋锁 spinlock_t slock; // 引用计数的 hash 表 RefcountMap refcnts; // weak 引用全局 hash 表 weak_table_t weak_table; }

游客bnlxddh3fwntw 2020-04-13 15:27:39 0 浏览量 回答数 0

回答

引用计数法、引用链法

游客pklijor6gytpx 2019-12-02 03:14:19 0 浏览量 回答数 0

回答

iOS的内存分三段,Text段存运行时代码,Stack段存编译时申请空间的数据,Heap段存运行时申请空间的数据。NSString的init方法就是把@""付给这个指针,同:initWithString:@"",同 = @""。iOS会给@""(或@"abcd")在编译时就分配内存,放在Stack段。Stack段是从低位开始向高位使用,不受引用计数控制。NSArray的init方法则是在运行时才分配空间的,放在Heap段。Heap段是从高位开始的,受引用计数控制。

a123456678 2019-12-02 03:12:21 0 浏览量 回答数 0

回答

一、垃圾回收:python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对Python语言来讲,对象的类型和内存都是在运行时确定的。这也是为什么我们称Python语言为动态类型的原因(这里我们把动态类型可以简单的归结为对变量内存地址的分配是在运行时自动判断变量类型并对变量进行赋值)。 二、引用计数:Python采用了类似Windows内核对象一样的方式来对内存进行管理。每一个对象,都维护这一个对指向该对对象的引用的计数。当变量被绑定在一个对象上的时候,该变量的引用计数就是1,(还有另外一些情况也会导致变量引用计数的增加),系统会自动维护这些标签,并定时扫描,当某标签的引用计数变为0的时候,该对就会被回收。 三、内存池机制Python的内存机制以金字塔行,-1,-2层主要有操作系统进行操作,    第0层是C中的malloc,free等内存分配和释放函数进行操作;    第1层和第2层是内存池,有Python的接口函数PyMem_Malloc函数实现,当对象小于256K时有该层直接分配内存;    第3层是最上层,也就是我们对Python对象的直接操作; 在 C 中如果频繁的调用 malloc 与 free 时,是会产生性能问题的.再加上频繁的分配与释放小块的内存会产生内存碎片. Python 在这里主要干的工作有: 如果请求分配的内存在1~256字节之间就使用自己的内存管理系统,否则直接使用 malloc. 这里还是会调用 malloc 分配内存,但每次会分配一块大小为256k的大块内存. 经由内存池登记的内存到最后还是会回收到内存池,并不会调用 C 的 free 释放掉.以便下次使用.对于简单的Python对象,例如数值、字符串,元组(tuple不允许被更改)采用的是复制的方式(深拷贝?),也就是说当将另一个变量B赋值给变量A时,虽然A和B的内存空间仍然相同,但当A的值发生变化时,会重新给A分配空间,A和B的地址变得不再相同

茶什i 2019-12-02 03:09:02 0 浏览量 回答数 0

回答

用打开文件来说明:如果是共享的方式打开,系统会在文件表中的引用计数增1,这个文件表是整个系统所有进程共享的,关闭文件后,引入计数会减1;当引入计数变为0时,系统才会从内存中删除这个文件表;如果不关闭,这个文件表就一直被留在内存中了;如果是独占的方式打开,表示当前进程占用了这个文件(资源),在我不关闭之前,其它用户无法再打开这个文件,这说明了为什么要关闭(用完了总得让其它人来用把);

a123456678 2019-12-02 02:55:52 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 企业建站模板