作者存档: 朱坤乾 - 第11页

text配置表优化

项目中字符串配置表是最大的一张表,足足有一万多条记录。

我们目前的存储方式是按csv类似格式存为scriptableobject。这张表的解析基本上占用总解析时间的25%~35%,因此优化这张表非常有必要。

查看了下text表中。其中重复内容大概按25%左右。因为表是按key,value键值对存储,计算了下key占用了45%的空间,这里优化的余地非常大。

1、不再存储key,而是将key改为int型的hashcode,这样,可以节省45%的空间

以下是java中的hashcode实现,测试了下,目前没发现有重复。

public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;

for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

2、针对有重复的value的情况,另存一个Map<hashcode,hashcode>,如果发现在map中存在当前使用的hashcode,则替代为使用map中的对应的value hashcode去查找。这样可以再减少25%的空间。

android生成的keystore默认密码

好吧,我们一个项目开发人员一不小心使用了默认生成的debug.keystore提交了app,结果线上无法换keystore,我们只好将debug.keystore拿过来用了。

debug.keystore默认密码是 android。

unity3d 中尽量避免使用foreach

foreach会消耗掉额外的内存,生成gc alloc,为了压榨手机的最后一部分性能,尽量避免使用foreach。

遍历数组直接使用:

for(int m=0;m<array.length;m++){

// array[m] 操作

}

遍历dictinory使用,这种方式不会造成gc

  • var enumerator = dummyDic.GetEnumerator();
  • while (enumerator.MoveNext()) {
  • // loop body goes here
  • }

unity命令和打包。

针对不同的平台(android/ios/pc),unity会对不同平台进行针对性优化。

因此如果要针对不同平台打包,最好针对每个平台将项目目录复制出来一份。这样可以避免unity发现平台转化了,对资源进行重新优化。当然了,如果做的游戏小,这点时间是可以忽略不计的。可惜我们的项目转一次资源就得半小时-.-!!。

vs2013下将文件使用unix结束符保存

There are inconsistent line endings in the ‘Assets/Scripts/ui/Mail/MailPrefab.cs’ script. Some are Mac OS X (UNIX) and some are Windows.
This might lead to incorrect line numbers in stacktraces and compiler errors. Many text editors can fix this using Convert Line Endings menu commands.

原因是因为vs下使用 “CR LF”结尾(Windows平台), unity下默认使用”LF”结尾(Unix平台)。

vs下想改为使用LF结尾,打开需要修改的文件,然后“文件->高级保存选项” 行尾选择“Unix (LF)”保存。

对于我们工程数十个文件来说,这不是很优雅的解决方式,幸好早有先人提供更好的方案。

http://www.grebulon.com/software/stripem.php

这个vs插件,可以将项目中所有文件以 LF 结束符保存。

jenkins将mac os 建立为slave节点

我们手游项目,需要支持android/ios,android支持在linux下打包。ios必须要mac上进行打包。

持续集成我们使用了jenkins,找了一台mac mini做为slave。

一开始使用的是java web start。结果试了各种方法得到结论,java web start特别方便,最好不要在mac上使用,因为担心java的安全问题,mac上的java web start根本无法使用。

参考了文章:https://blog.samsaodev.com/how-to-setup-a-jenkins-slave-running-mac-osx-for-ios-projects-part-1/

在ssh-add那一步如果遇到:SSH_AGENT_FAILURE 错误,可以先执行下 eval $(ssh-agent) 试试能否解决问题。

使用ssh建立slave节点。

在mac os 上一直无法使用username/password模式登陆,发现原来mac os因为安全原因,禁止了没有交互的ssh登陆。这里只能使用rsa private key 进行登陆。

在master server上生成key。

然后将public key 复制至slave server。

登陆slave时失败了,查看slave server上的/var/log/secure:sshd[12053]:  Address 10.234.49.36 maps to localhost, but this does not map back to the address – POSSIBLE BREAK-IN ATTEMPT!

是因为:是因为DNS服务器把 10.234.x.x 的地址都反向解析成 localhost ,而DNS服务器不是自己的,不能改。 解决的办法就是,编辑 ssh 客户端的 /etc/hosts 文件,把出问题的IP 地址和主机名加进去,就不会报这样的错了。

两台机器之间使用ssh key登陆,默认使用本地当前的用户名,如果不是,则需明确指定用户名。

在jenkins上使用ssh key登陆时,密码必须为空。同时指定private key 所在路径。

OK,添加jenkins子节点成功。

测试配置数据占用的内存大小

游戏中一直不是很清楚配置数据占用了多少内存,现在是使用json转c#对象,转化使用时间也不清楚。

scriptableobject和json相比也不知道谁的性能更优。

现在使用的是dictionary来存储的数据,和hashtable相比谁更快,不知道。现在使用的key是string,使用int是否更快。

以上都需要测试结果:

1、先测试占用的内存。

打一个空场景。

占用的内存如图:

  • total 44.6
  • unity 13.8
  • mono 0.7
  • gfxdriver 17.0
  • fmod 252
  • profiler 12.2
  • assets 19.7
  • other 9.8
  • builtin resources 243.6
  • not saved 26.7
  • scene memory 8.7

原来的工程场景和资源太多了,打包一次太费时间,这里重新建一个工程

内存占用如图:

  • total 18.6
  • unity 2.7
  • mono 0.5
  • gfxdriver 3.3
  • fmod 310k
  • profiler 12.1
  • assets 1.5
  • other 2.1
  • builtin resources 231.1k
  • not saved 145.6k
  • scene memory 15.5k

log_config配置文件大小1M,json未压缩。使用resource.load导入内存增加:1.1M和原文件基本相同。多次使用Resources.load只会增加一份内存。(在assets中显示为text asset)

感觉消耗的内存由other移至assets中。再测试一次,unity死掉了。再重启测试一次,果真如此,other中asset0的东西没有了,assets中多了一个textasset名为log_config。

TextAsset text=Resources.Load(“log_config”) as TextAsset;
TextAsset text2 = Resources.Load(“log_config”) as TextAsset;

连续两行,内存也没有多少变化,TextAsset可能都是引用。果真只是引用。

神奇了。使用Resources.unload后,TextAsset log_config被释放内存。但是other中没有增加内存!!!

我把json中的字符串放入textbox中,内存消耗变的巨大:

主要是other中的managedHeap.usedSize变为了71M,在simple界面中可以看到mono也同步变为了71M。

测试结果,使用Resources.load 加载后,然后使用unload释放掉对象内存,但是好像该对象还可以继续使用 -.-!!。难道是因为内存区还保留着数据导致的?unloadAssets,如果被引用对象再次被使用,会从被加载的地方重新被加载。所以,一个对象完全不被使用后,再unloadAssets。

在这里,我们的配置文件被转化为了c#对象,所以可以直接unload掉,释放内存。

minijson中有个东西占用了内存,转换申请了6M内存,一直没有被释放。如果再转换一个小json比如“{}”就会将内存释放掉。

使用json进行转换,中间产生了8M内存占用,既使将引用对象设置为null,不调用GC.collection()也不会回收内存。

text asset转为json消耗2秒,json存入dictionary消耗1.5秒。

开始测试scriptableobject。

没有测试protobuf,scriptableobject比未压缩json容量仅为20%,加载时间仅为10%,内存消耗仅为20%。完全可以替代json。

另外,字符串可以考虑7z压缩,这样可以使用更小的内存,仅多消耗一点CPU。

scriptableobject无法定义为泛型类。

 

unity3d 动态给按钮添加事件

UIEventListener.Get(bt1).onClick = click;

bt1 是按钮的gameobject

 

游戏登陆场景掉祯排查

我们游戏中场景经常出现掉祯的现象。

fps会突然从30降至15。

原来一直没有找到原因,最近学习unity,使用profiler看运行时的情况,看到我的手机上,掉祯出现时,cpu usage会突然飙升,同时gpu usage会也同步飙升。

cpu上升显示是camera.render使用率大量增加。

gpu上升定位至是RenderForwardOpaque.Render占用时间大量增加导致的。

 

 

 

 

unity3d 中捕获所有的异常

void Start () {
// System.AppDomain.CurrentDomain.UnhandledException +=new System.UnhandledExceptionEventHandler(  _erroHandler);
//Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// Application.Run(new Game());
Application.RegisterLogCallback(_erroHandler);
Application.RegisterLogCallbackThreaded(_erroHandler);
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}

private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Debug.Log(“Application_threadException”);
}

void _erroHandler(string name,string stack,LogType type)
{
}