ssh2开发 初始化hashmap对象到内存 供全局使用如何实现

比如程序运行的时候,初始化时加载用户信息表里的数据,以键值对的形式放到hashmap中
之后其他方法可以直接调用这个全局的hashmap的到用户的信息。。。。


问题补充:这么说只需要定义成static就行了吗

回答: ssh2开发 初始化hashmap对象到内存 供全局使用如何实现

  1. static 表示全局
    final 表示只读
    这两者结合则实现了,单例共享。
    建议有时间的话,读一读这个:
    http://mougaidong-163-com.iteye.com/blog/994949

Ophone 软件开发套件 SDK 1.5可供下载了(免费滴哦)

  1. Q
    偶最近登录了Ophone SDN,感觉比较好,在那里可以下载最新的OPhone SDK ;查阅OPhone官方的开发文档;建立自己的OPhone软件项目;与其他开发者交流您的开发经验。

    并有最新 Ophone 软件开发套件 SDK 1.5可供下载了(免费滴哦),希望给大家带来帮助,不算过期吧?!!!
    总之 偶觉得对于Ophone开发者来讲这是一个很好的学习地方!

    下载地址:()
  2. A
    谢谢共享

要存1000到2000个对象到内存里面,用那种数据结构比较好

  1. Q
    现在的需求是,大约有1000到2000个对象要保存到内存(ServletContext)里面,然后每个对象都有一个唯的标志,比如说QQ号码(或电子邮箱)

    现在给出600到800个QQ号码(或电子邮箱)把这600到800个对象从内存里面找出来

    用什么数据结构去保存比较方便LIST SET MAP还是什么?怎样才能查出来的又快又好?

    先谢谢大家了
  2. A
    说下Map的原理,JavaAPI使用了一个默认大小数组,这个大小你可以自己设置Hash因子
    1.put一个数据的时候先计算出Key的Hashcode
    2.然后使用这个Hashcode对数组的大小进行求余
    3.余数就是对象应该放入的数组位置,而这个数组里装着一个链表,一般情况是没有哈希冲突的,所以可以直接存入,如果该位置已经存在一个元素,被称为哈希冲突,这个时候就直接放入链表末尾(查找的时候也是这个步骤,当发现有冲突就进行遍历)

    这也是为什么Hash表要求重写hashcode和equals方法

spring+springmvc,在项目中如何初始化一些数据保存下来供其它类调用?

  1. Q
    比如项目中经常会向某个文件夹写入文件,之前是每次在controller中调用req.getSession().getServletContext().getRealPath(...)去获取文件夹的真实路径的,有没有一种方案在项目一启动就把这个文件夹真实地址读出来作为一个类的public static 变量,可供其他service直接访问?小弟学生一枚,请多多指教spring+springmvc,在项目中如何初始化一些数据保存下来供其它类调用?
  2. A
    楼主你知道tomcat在配置servlet时有个<start-up-onload>参数吗, 可以配置一个这样的servlet,里面就可以进行一些项目全局属性的设置和初始化,你可以将你要文件夹的真实路径在里面就取出来赋值给一个类 的静态属性,这样tomcat启动时发现了这个servlet是start-up-onload就会立即执行,还可以通过tomcat的ServletContextListener监听ServletContext。当创建ServletContext时,激发 contextInitialized(ServletContextEvent sce)方法;当销毁ServletContext时,激发contextDestroyed(ServletContextEvent sce)方法。
    用这个监听器,tomcat启动和停止前你想干什么干什么

manqy-to-one lazy=false 无法延迟加载而读取大量对象到内存

  1. Q
    大家好,请教一个关于延迟加载的问题,
    配置文件,<many-to-one class="User" cascade="none" column="uid" lazy="false"/>
    这样的话 我读取数据库的数据,我就要全部加载,这会造成效率降低
    但如果不这样的话,在service层调用dao层读取数据库时,由于在session在dao层已经关闭,且没有初始化,当我要读取collection中数据时,service层会抛错lazyinitialexception
    或者就在dao层完成对collection的初始化,但这样,与lazy无关,效果和false一样

    还有一个问题,关于cascade,写成none后,无法删除主表和从表相关记录,我只想这样,删主表时能自动删除从表记录,但删从表不会影响主表,请问这cascade该用何属性值

    谢谢
  2. A
    1、service层会抛错lazyinitialexception   考虑OpenSessionInView

    2、删主表时能自动删除从表记录,但删从表不会影响主表,请问这cascade该用何属性值
       这应该在one-to-many 端设置cascade  或者在数据库端设置外键的 on delete cascade

ssh2整合 spring 注入对象为空

  1. Q
    在tomact服务启动之后我在Action里对象set方法 打印出对象 证明是注入进去的 ,, 当我调用Action里面对象的时候 就提示我空指针异常
    如果使用getBean 的话是可以得到对象的

    web.xml
    			   		<property name="driverClassName" value="${jdbc.driver}"></property>
    
    <property name="url" value="${jdbc.url}"></property>
    <property name="username" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.pwd}"></property>
    <property name="maxIdle" value="${jdbc.maxIdleTime}"></property>
    <property name="maxActive" value="${jdbc.maxPoolSize}"></property>
       </bean>
       <bean id="sessionFactorydao" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
       <property name="dataSource" ref="dataSource" />
       <property name="mappingDirectoryLocations">
       <list>
       <value>classpath:/entity/</value>
    </list>
       </property>
    <property name="hibernateProperties">
    <value>
    hibernate.dialect=org.hibernate.dialect.SQLServerDialect
    <!-- hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect -->
    hibernate.show_sql=true
    </value>
    </property>

       </bean>
       <bean id="p" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
       <property name="locations">
       <list><value>classpath:/jdbc.properties</value></list>
    </property>
    </bean>
    <bean id="txManage" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactorydao" />
    </bean>
    <tx:advice id="TxtransactionManage" transaction-manager="txManage">
    <tx:attributes>
    <tx:method name="save*" propagation="REQUIRED"  />
    <tx:method name="delete*" propagation="REQUIRED" />
    <tx:method name="update*" propagation="REQUIRED" />
    </tx:attributes>
    </tx:advice>
    <aop:config>
    <aop:pointcut id="userDaosearch" expression="execution( * ouyang.UserService.*.*(..))" />
    <aop:advisor advice-ref="TxtransactionManage"  pointcut-ref="userDaosearch" />
    </aop:config>
    <bean id="spring" class="util.SpringUtil" />
    <bean id="UserDao" class="testDAO.UserDao">
    <property name="sessionFactory" ref="sessionFactorydao" />
    </bean>
    <bean id="UserService" class="UserService.UserService">
    <property name="userDao" ref="UserDao" />
    </bean>
    <bean id="userAction" class="Action.UserAction">
    <property name="userService" ref="UserService" />

    </bean>

       </beans>

    UserAction 

       package Action;

    import javax.servlet.http.HttpServletRequest;

    import org.apache.struts2.ServletActionContext;
    import org.apache.xbean.spring.context.ClassPathXmlApplicationContext;
    import org.springframework.context.ApplicationContext;
    import org.springframework.web.struts.ActionSupport;

    import testDAO.IUserDao;

    import UserService.IUserService;
    import UserService.UserService;


    public class UserAction extends ActionSupport{

    IUserService userService;
    public void setUserService(IUserService userService) {
    System.out.println("注入进来了");
    this.userService = userService;
    }
    public IUserService getUserService() {
    return userService;
    }
    public String login(){
    HttpServletRequest request = ServletActionContext.getRequest();
    String name = request.getParameter("name");
    String pwd = request.getParameter("pwd");
    //ApplicationContext app= new ClassPathXmlApplicationContext("applicationContext.xml");
    //userService =(UserService)app.getBean("UserService");
    System.out.println(userService==null);
    if(userService.Login(name, pwd)){
    request.setAttribute("success", "登陆成功");
    }else{
    request.setAttribute("success", "登陆失败");
    }
    return "index";
    }

    }

    问题补充:ethen 写道把错误信息贴出来看看吧
    java.lang.NullPointerException
    Action.UserAction.login(UserAction.java:35)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:441)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:280)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:243)
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:165)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:252)
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:122)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:179)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:75)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:94)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:235)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:89)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:130)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:126)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:138)
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:165)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:179)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:237)
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:488)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

    问题补充:aabcc 写道没看见 struts.xml

    struts里头action里配置的是 class = "userAction" 还是 class="Action.UserAction"?

    struts2-spring-plugin.jar 加进去了没?


    写的是Action.userAction  这个包也有

    struts.xml
      <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    <constant name="struts.action.extension" value="action" />
    <constant name="struts.objectFactory" value="spring" />


    <package name="custom" extends="struts-default">
    <action name="user" class="Action.UserAction">
    <result name="index">/index.jsp</result>
    </action>
    </package>


    </struts>
  2. A
    那就改成 userAction

方法返回之前如何释放要返回对象的内存?

  1. Q
    我写的一个方法,值是一串长字符串,保存在一个指针里,请问如何在返回改值之前释放掉改值的内存?

    char * pBuf;
    return pBuf;


    pbuf这个指针大小在1Kb之上。
  2. A
    Dll和调用者之间最好是谁分配谁释放原则,在构造函数中分配,在析构函数中释放,这是常识

jquery ajax如何使图片的热点的"alt"取得数据。--ssh2开发问题

  1. Q
    我图片上有12个热点!
     $(document).ready(function(){
        $("area").each(function(){
          $("area").click(function(){
           var aname = $(this).attr("alt");
            $("area").index();
            $("body").prepend("<div id='mapDiv'></div>");
            $("#mapDiv").html("<span>"+aname+"</span>");
              .......省略向action中传值部分
          }).mousedown(function(){
            $("#mapDiv").remove();
          });
        });
      });获取数据向后台传值的时候竟然传了12个!
    <html>代码:
    <area alt="1"/>
    .
    .
    .
    .
    <area alt="2"/>描述的够清楚了,求解!!!
  2. A
    $("area").each(function()去掉

     $("area").click已经包含each的功能了
    再加each,相当于绑定click12次了

[百度分享]iOS内存暴增问题追查与使用陷阱

  1. Q
    iOS平台的内存使用引用计数的机制,并且引入了半自动释放机制;这种使用上的多样性,导致开发者在内存使用上非常容易出现内存泄漏和内存莫名的增长情况; 本文会介绍iOS平台的内存使用原则与使用陷阱; 深度剖析autorelease机制;低内存报警后的处理流程;并结合自身实例介绍内存暴增的问题追查记录以及相关工具的使用情况;
    TAG
    内存暴增,内存泄漏,autorelease;内存报警;
    iOS平台内存常见问题
    作为iOS平台的开发者,是否曾经为内存问题而苦恼过?内存莫名的持续增长,程序莫名的crash,难以发现的内存泄漏,这些都是iOS平台内存相关的常见问题;本文将会详细介绍iOS平台的内存管理机制,autorelease机制和内存的使用陷阱,这些将会解决iOS平台内存上的大部分问题,提高了程序的稳定性;
    1 iOS平台内存管理介绍
    iOS平台的内存管理采用引用计数的机制;当创建一个对象时使用alloc或者allWithZone方法时,引用计数就会+1;当释放对象使用release方法时,引用计数就是-1;这就意味着每一个对象都会跟踪有多少其他对象引用它,一旦引用计数为0,该对象的内存就会被释放掉;另外,iOS也提供了一种延时释放的机制AutoRelease,以这种方式申请的内存,开发者无需手动释放,系统会在某一时机释放该内存; 由于iOS平台的这种内存管理的多样性,导致开发者在内存使用上很容易出现内存泄漏或者程序莫名崩溃的情况,本文会详细介绍iOS平台内存的使用规范与技巧以及如何利用工具避免或者发现问题;
    下图是内存从申请到释放的一个完整示例:
    [百度分享]iOS内存暴增问题追查与使用陷阱

    [百度分享]iOS内存暴增问题追查与使用陷阱

    2 iOS平台内存使用原则
    2.1 对象的所有权与销毁
    2.1.1 谁创建,谁释放;
    如果是以alloc,new或者copy,mutableCopy创建的对象,则必须调用release或者autorelease方法释放内存;
    如果没有释放,则导致内存泄漏!
    2.1.2 谁retain,谁释放;
    如果对一个对象发送 retain消息,其引用计数会+1,则使用完必须发送release或者autorelease方法释放内存或恢复引用计数;
    如果没有释放,则导致内存泄漏!
    2.1.3 没创建且没retain,别释放
    不要释放那些不是自己alloc或者retain的对象,否则程序会crash;
    不要释放autorelease的对象,否则程序会crash;
    2.2 对象的深拷贝与浅拷贝
    一般来说,复制一个对象包括创建一个新的实例,并以原始对象中的值初始化这个新的实例。复制非指针型实例变量的值很简单,比如布尔,整数和浮点数。复制指 针型实例变量有两种方法。一种方法称为浅拷贝,即将原始对象的指针值复制到副本中。因此,原始对象和副本共享引用数据。另一种方法称为深拷贝,即复制指针 所引用的数据,并将其赋给副本的实例变量。
    2.2.1 深拷贝
    深拷贝的流程是 先创建一个新的对象且引用计数为1,并用旧对象的值初始化这个新对象;
    ClassA* objA = [[ClassA alloc] init];
    ClassA* objB = [objA copy];
    objB是一个新对象,引用计数为1,且objB的数据等同objA的数据;
    注意: objB需要释放,否则会引起内存泄漏!
    2.2.2 浅拷贝
    浅拷贝的流程是,无需引入新的对象,把原有对象的引用计数+1即可
    ClassA* objA = [[ClassA alloc] init];
    ClassA* objB = [objA retain];
    注意: objB需要释放,恢复objA的引用计数,否则会引起内存泄漏!
    2.3对象的存取方法
    2.3.1 属性声明和实现
    变量声明的常用属性类型包括readonly,assign,retain和copy;且系统会自动为声明了属性的变量生成set和get函数;
    readonly属性: 只能读,不能写;
    assign属性: 是默认属性,直接赋值,没有任何保留与释放问题;
    retain属性: 会增加原有对象的引用计数并且在赋值前会释放原有对象,然后在进行赋值;
    copy属性:  会复制原有对象,并在赋值前释放原有对象,然后在进行赋值;
    2.3.2 使用属性声明可能带来的隐患
    当一个非指针变量使用retain(或者copy)这个属性时,尽量不要显性的release这个变量;直接给这个变量置空即可;否则容易产生过度释放,导致程序crash; 例如:
    ClassA类的strName是NSString* 类型的变量且声明的属性为retain;
    ClassA.strName = nil;  /* 释放原有对象且对此对象赋值为空 */
    [ClassA.strName release]; /* strName内存可能已经被释放过了,将导致程序crash */
    Assign这个属性一般是非指针变量(布尔类型,整形等)时用这个类型;属于直接赋值型,不需要考虑内存的保留与释放;
    如果一个指针类型的变量使用assign类型的属性,有可能引用已经释放的变量;导致程序crash; 例如:
    ClassB* obj =[[[ClassB alloc] init] autorelease];
    ……
    ClassA.strName = obj; /* strName 指向obj的内存地址*/
    后续在使用ClassA.strName的时候, 因为obj是autorelease的,可能obj的内存已经被回收;导致引用无效内存,程序crash;
    3iOS平台AutoRelease机制
    3.1 自动释放池的常见问题
    大家在开发iOS程序的时候,是否遇到过在列表滑动的情况内存莫名的增长,频繁访问图片的时候内存莫名的增长,频繁的打开和关闭数据库的时候内存莫名的增长…… 这些都是拜iOS的autorelease机制所赐;具体分析如下:
    1: 滑动列表的时候,内存出现莫名的增长,原因可能有如下可能:
    1:没有使用UITableView的reuse机制; 导致每显示一个cell都用autorelease的方式重新alloc一次; 导致cell的内存不断的增加;
    2:每个cell会显示一个单独的UIView, 在UIView发生内存泄漏,导致cell的内存不断增长;
    2: 频繁访问图片的时候,内存莫名的增长;
    频繁的访问网络图片,导致iOS内部API,会不断的分配autorelease方式的buffer来处理图片的解码与显示; 利用图片cache可以缓解一下此问题;
    3: 频繁打开和关闭SQLite,导致内存不断的增长;
    在进行SQLite频繁打开和关闭操作,而且读写的数据buffer较大,那么SQLite在每次打开与关闭的时候,都会利用autorelease的方式分配51K的内存; 如果访问次数很多,内存马上就会顶到几十兆,甚至上百兆! 所以针对频繁的读写数据库且数据buffer较大的情况, 可以设置SQLite的长连接方式;避免频繁的打开和关闭数据库;
    3.2 自动释放池的概念
    NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声名为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。
    ClassA *obj1 = [[[ClassA alloc] init] autorelease]; //retain count = 1,把此对象加入autorelease pool中
    NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。如果此时数组中成员的retain count为1,那么release之后,retain count为0,对象正式被销毁。如果此时数组中成员的retain count大于1,那么release之后,retain count大于0,此对象依然没有被销毁,内存泄露。
    3.3 自动释放池的作用域与嵌套
    AutoreleasePool是可以嵌套使用的!
    池是被嵌套的,嵌套的结果是个栈,同一线程只有当前栈顶pool实例是可用的:
    [百度分享]iOS内存暴增问题追查与使用陷阱

    当短生命周期内,比如一个循环中,会产生大量的临时内存,可以创建一个临时的autorelease pool,这样可以达到快速回收内存的目的;
    3.4 自动施放池的手动创建与自动创建
    3.4.1 需要手动创建自动释放池
    ●如果你正在编写一个不是基于Application Kit的程序,比如命令行工具,则没有对自动释放池的内置支持;你必须自己创建它们。
    ●如果你生成了一个从属线程,则一旦该线程开始执行,你必须立即创建你自己的自动释放池;否则,你将会泄漏对象。
    ●如果你编写了一个循环,其中创建了许多临时对象,你可以在循环内部创建一个自动释放池,以便在下次迭代之前销毁这些对象。这可以帮助减少应用程序的最大内存占用量。
    3.4.2 系统自动创建自动释放池
    Application Kit会在一个事件周期(或事件循环迭代)的开端—比如鼠标按下事件—自动创建一个自动释放池,并且在事件周期的结尾释放它.
    4 iOS平台内存使用陷阱
    4.1 重复释放
    在前文已经提到,不要释放不是自己创建的对象;
    释放自己的autorelease对象,app会crash;
    释放系统的autorelease对象,app会crash;
    4.2 循环引用
    循环引用,容易产生野引用,内存无法回收,最终导致内存泄漏!可以通过弱引用的方式来打破循环引用链;所谓的弱引用就是不需要retain,直接赋值的方式,这样的话,可以避免循环引用的问题,但是需要注意的是,避免重复释放的问题;
    5 iOS平台内存报警机制
    由于iOS平台的内存管理机制,不支持虚拟内存,所以在内存不足的情况,不会去Ram上创建虚拟内存;所以一旦出现内存不足的情况,iOS平台会通知所有已经运行的app,不论是前台app还是后台挂起的app,都会收到 memory warning的notice;一旦app收到memory warning的notice,就应该回收占用内存较大的变量;
    5.1 内存报警处理流程
    1: app收到系统发过来的memory warning的notice;
    2: app释放占用较大的内存;
    3: 系统回收此app所创建的autorelease的对象;
    4: app返回到已经打开的页面时,系统重新调用viewdidload方法,view重新加载页面数据;重新显示;
    5.2 内存报警测试方法
    在Simulate上可以模拟低内存报警消息;
    iOS模拟器 -> 硬件 -> 模拟内存警告;
    开发者可以在模拟器上来模拟手机上的低内存报警情况,可以避免由于低内存报警引出的app的莫名crash问题;
    6 iOS平台内存检查工具
    6.1 编译和分析工具Analyze
    iOS的分析工具可以发现编译中的warning,内存泄漏隐患,甚至还可以检查出logic上的问题;所以在自测阶段一定要解决Analyze发现的问题,可以避免出现严重的bug;
    内存泄漏隐患提示:
    Potential Leak of an object allocated on line ……
    数据赋值隐患提示:
    The left operand of …… is a garbage value;[
    对象引用隐患提示:
    Reference-Counted object is used after it is released;
    以上提示均比较严重,可能会引起严重问题,需要开发者密切关注!
    6.2 内存检测工具
    6.2.1 内存泄漏检测工具—Leak
    Leak工具可以很容易的统计所有内存泄漏的点,而且还可以显示在那个文件,哪行代码有内存泄漏,这样定位问题比较容易,也比较方面;但是Leak在统计内存泄漏的时候会把autorelease方式的内存也统计进来; 所以我们在查找内存泄漏情况的时候,可以autorelease的情况忽略掉;
    Leak工具:
    [百度分享]iOS内存暴增问题追查与使用陷阱

    通过Leak工具可以很快发现代码中的内存泄漏,通过工具也可以很快找到发生内存泄漏的代码段:
    [百度分享]iOS内存暴增问题追查与使用陷阱

    6.2.2 内存猛增检测工具—Allocations
    Allocations工具可以很容易的列出所有分配内存的点,这样我们可以按照分配内存大小来进行排序, 这样可以很容易的发现哪些点分配的内存最多,而且是持续分配,这样我们来针对性的分析这些持续分配较大内存的地方;
    [百度分享]iOS内存暴增问题追查与使用陷阱

    此工具会显示出所有申请内存的地方,并统计申请的次数和大小; 从这个列表中可以找出内存申请次数最多且申请内存最大的语句;从而分析出哪些地方使用的内存最多,进而可以优化和改进;
    [百度分享]iOS内存暴增问题追查与使用陷阱

    上图是按照申请内存多少来排序的,可以方便的了解哪些代码申请的内存多;

    7 参考资料
    http://www.cocoachina.com/bbs/read.php?tid=15963
    http://developer.apple.com/library/IOs/navigation/
  2. A
    看不出哪里好,我用C语言才偶尔有这个问题,高级语言我都不可能这么愚蠢!

内存分配

  1. Q
    Java内存管理(一、内存分配)
    关键字: 内存分配,常量池 
    一、Java内存分配
    1、 Java有几种存储区域?
    * 寄存器
         -- 在CPU内部,开发人员不能通过代码来控制寄存器的分配,由编译器来管理
    * 栈
         -- 在Windows下, 栈是向低地址扩展的数据结构,是一块连续的内存的区域,即栈顶的地址和栈的最大容量是系统预先规定好的。
         -- 优点:由系统自动分配,速度较快。
         -- 缺点:不够灵活,但程序员是无法控制的。
         -- 存放基本数据类型、开发过程中就创建的对象(而不是运行过程中)
    * 堆
         -- 是向高地址扩展的数据结构,是不连续的内存区域
         -- 在堆中,没有堆栈指针,为此也就无法直接从处理器那边获得支持
         -- 堆的好处是有很大的灵活性。如Java编译器不需要知道从堆里需要分配多少存储区域,也不必知道存储的数据在堆里会存活多长时间。
    * 静态存储区域与常量存储区域
         -- 静态存储区用来存放static类型的变量
         -- 常量存储区用来存放常量类型(final)类型的值,一般在只读存储器中
    * 非RAM存储
         -- 如流对象,是要发送到另外一台机器上的
         -- 持久化的对象,存放在磁盘上
    2、 java内存分配
         -- 基础数据类型直接在栈空间分配;
         -- 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收;
         -- 引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量;
         -- 方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完后从栈空间回收;
         -- 局部变量 new 出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收;
         -- 方法调用时传入的 literal 参数,先在栈空间分配,在方法调用完成后从栈空间释放;
         -- 字符串常量在 DATA 区域分配 ,this 在堆空间分配;
         -- 数组既在栈空间分配数组名称, 又在堆空间分配数组实际的大小!
    3、Java内存模型
    * Java虚拟机将其管辖的内存大致分三个逻辑部分:方法区(Method Area)、Java栈和Java堆。
        -- 方法区是静态分配的,编译器将变量在绑定在某个存储位置上,而且这些绑定不会在运行时改变。
            常数池,源代码中的命名常量、String常量和static 变量保存在方法区。
        -- Java Stack是一个逻辑概念,特点是后进先出。一个栈的空间可能是连续的,也可能是不连续的。
            最典型的Stack应用是方法的调用,Java虚拟机每调用一次方法就创建一个方法帧(frame),退出该方法则对应的  方法帧被弹出(pop)。栈中存储的数据也是运行时确定的?
        -- Java堆分配(heap allocation)意味着以随意的顺序,在运行时进行存储空间分配和收回的内存管理模型。
            堆中存储的数据常常是大小、数量和生命期在编译时无法确定的。Java对象的内存总是在heap中分配。
    4、Java内存分配实例解析
         常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。
         常量池在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用。
         例:
         String s1=new String("kvill");
         String s2=s1.intern();
         System.out.println( s1==s1.intern() );//false
         System.out.println( s1+" "+s2 );// kvill kvill
         System.out.println( s2==s1.intern() );//true
         这个类中事先没有声名”kvill”常量,所以常量池中一开始是没有”kvill”的,当调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在。s1==s1.intern()为false说明原来的“kvill”仍然存在;s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。

     

    String 常量池问题
    (1) 字符串常量的"+"号连接,在编译期字符串常量的值就确定下来, 拿"a" + 1来说,编译器优化后在class中就已经是a1。
         String a = "a1";  
         String b = "a" + 1;  
         System.out.println((a == b)); //result = true 
         String a = "atrue";  
         String b = "a" + "true";  
         System.out.println((a == b)); //result = true 
         String a = "a3.4";  
         String b = "a" + 3.4;  
         System.out.println((a == b)); //result = true
    (2) 对于含有字符串引用的"+"连接,无法被编译器优化。
         String a = "ab";  
         String bb = "b";  
         String b = "a" + bb;  
         System.out.println((a == b)); //result = false
         由于引用的值在程序编译期是无法确定的,即"a" + bb,只有在运行期来动态分配并将连接后的新地址赋给b。
    (3) 对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝并存储到自己的常量池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。
         String a = "ab";  
         final String bb = "b";  
         String b = "a" + bb;  
         System.out.println((a == b)); //result = true
    (4) jvm对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b。
         String a = "ab";  
         final String bb = getbb();  
         String b = "a" + bb;  
         System.out.println((a == b)); //result = false  
         private static string getbb() { 
           return "b";  
         }
    (5) String 变量采用连接运算符(+)效率低下。
         String s = "a" + "b" + "c"; 就等价于String s = "abc"; 
         String a = "a"; 
         String b = "b"; 
         String c = "c"; 
         String s = a + b + c; 
         这个就不一样了,最终结果等于: 
           Stringbuffer temp = new Stringbuffer(); 
           temp.append(a).append(b).append(c); 
           String s = temp.toString(); 
    (6) Integer、Double等包装类和String有着同样的特性:不变类。 
         String str = "abc"的内部工作机制很有代表性,以Boolean为例,说明同样的问题。 
         不变类的属性一般定义为final,一旦构造完毕就不能再改变了。 
         Boolean对象只有有限的两种状态:true和false,将这两个Boolean对象定义为命名常量: 
         public static final Boolean TRUE = new Boolean(true); 
         public static final Boolean FALSE = new Boolean(false); 
         这两个命名常量和字符串常量一样,在常数池中分配空间。 Boolean.TRUE是一个引用,Boolean.FALSE是一个引用,而"abc"也是一个引用!由于Boolean.TRUE是类变量(static)将静态地分配内存,所以需要很多Boolean对象时,并不需要用new表达式创建各个实例,完全可以共享这两个静态变量。其JDK中源代码是: 
         public static Boolean valueOf(boolean b) { 
           return (b ? TRUE : FALSE); 
         } 
         基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是JSE 5.0提供的新功能。 Boolean b1 = 5>3; 等价于Boolean b1 = Boolean.valueOf(5>3); //优于Boolean b1 = new Boolean (5>3); 
        static void foo(){ 
            boolean isTrue = 5>3;  //基本类型 
            Boolean b1 = Boolean.TRUE; //静态变量创建的对象 
            Boolean b2 = Boolean.valueOf(isTrue);//静态工厂 
            Boolean b3 = 5>3;//自动装箱(autoboxing) 
            System.out.println("b1 == b2 ?" +(b1 == b2)); 
            System.out.println("b1 == b3 ?" +(b1 == b3)); 
            Boolean b4 = new Boolean(isTrue);////不宜使用 
            System.out.println("b1 == b4 ?" +(b1 == b4));//浪费内存、有创建实例的时间开销 
        } //这里b1、b2、b3指向同一个Boolean对象。
    (7) 如果问你:String x ="abc";创建了几个对象? 
         准确的答案是:0或者1个。如果存在"abc",则变量x持有"abc"这个引用,而不创建任何对象。 
         如果问你:String str1 = new String("abc"); 创建了几个对象? 
         准确的答案是:1或者2个。(至少1个在heap中)
    (8) 对于int a = 3; int b = 3;
         编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。
    5、堆(Heap)和非堆(Non-heap)内存
         按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”
         可以看出JVM主要管理两种类型的内存:堆和非堆。
         简单来说堆就是Java代码可及的内存,是留给开发人员使用的;
         非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。 
    堆内存分配
         JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;
         JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。
         默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。
         因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。 
    非堆内存分配
         JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
         由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 
    例子
         -Xms256m
         -Xmx1024m
         -XX:PermSize=128M
         -XX:MaxPermSize=256M
  2. A
    看看,学习。