I'm trying to make my application throw MemoryError by creating a very long string, but it hangs instead of throwing it.
I tried this with air sdk 3.4 and 3.8, both release and debug builds.
Sometimes when I close the app in a force way, eclipse shows something like app exited with error code:out of memory.
I also noticed that console contains line [Unload SWF] myapp.swf after executing the code(if you add trace(str.length) after doubling the string, you'll see that it happens after length 369098752).
You can see here AS3 Reference for MemoryError that this is legitimate way of causing MemoryError.
So, how can I really catch those MemoryErrors instead of allowing app to crash?
Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="onCreation(event)"
>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
import avmplus.getQualifiedClassName;
protected var str:String = 'ssssssssssssssssssssss';
protected function onCreation(event:FlexEvent):void{
var serverString:String = unescape(Capabilities.serverString);
try{
while(true){
str+=str;
}
}catch(e:MemoryError){
Alert.show('memoryError');
}
}
]]>
</fx:Script>
</s:WindowedApplication>
update:
I improved test app, now you can clearly see that no error or uncaught error is thrown.
It crashes when memory usage reaches 1700-1750MB.
I found some bugs that resemble my case in bugbase, but they are related to air 2.x and marked as fixed/not a bug. I can't find any similar bug for air 3.x.
Bug: App crashes when allocates >1.7GB
Bug: App crashes when approaches 2GB
Can anybody reproduce?
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
applicationComplete="onCreation(event)"
>
<fx:Script>
<![CDATA[
import flash.utils.setInterval;
import mx.controls.Alert;
import mx.events.FlexEvent;
import avmplus.getQualifiedClassName;
protected var vectors:Vector.<Vector.<uint>>= new Vector.<Vector.<uint>>();
protected function onCreation(event:FlexEvent):void{
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,onUncaughtError);
var serverString:String = unescape(Capabilities.serverString);
trace('vm version: '+System.vmVersion);
setInterval(increaseMemoryUsage,100);
}
protected function increaseMemoryUsage():void{
try{
var vector:Vector.<uint> = new Vector.<uint>();
vector.length = 1024*1024/4;//1MB
vectors.push(vector);
System.gc();
trace(vectors.length*1+'MB');
trace('total: '+System.totalMemoryNumber+', private: '+System.privateMemory+', free: '+System.freeMemory);
totalMemoryDisplay.text=''+int(System.totalMemoryNumber/(1024*1024))+'MB';
}catch(e:MemoryError){
trace('it catches!');
Alert.show('memoryError');
}catch(e:Error){
trace('error'+e.errorID);
}
}
protected function onUncaughtError(e:UncaughtErrorEvent):void{
trace('it is uncaught!');
}
]]>
</fx:Script>
<s:Label id="totalMemoryDisplay" />
</s:WindowedApplication>
Related
I'm using FlashBuilder 4.7 and Flex SDK 4.11.
I've created new Mobile Flex Project and created 2 files in default package:
bestPairs.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:bestpairs="*"
width="640"
height="480">
<s:layout>
<s:BasicLayout />
</s:layout>
<s:Label text="Hello World!" horizontalCenter="0" verticalCenter="0" />
<s:Button id="myButton"/>
</s:Application>
Main.as:
package
{
import flash.events.MouseEvent;
import mx.events.FlexEvent;
import spark.components.Button;
import spark.components.Group;
public class Main extends Group
{
public var myButton:Button;
public function Main()
{
super();
this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
trace("main!");
}
private function onCreationComplete(e:FlexEvent):void {
this.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
myButton.addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void {
// Do something
trace("clicked!");
}
}
}
because I want to split code from design. Anyway trace are not showing at all. In Debug Mode too. I tried also this: https://stackoverflow.com/a/3627826/1264375 (I made flex-config.xml file in src/config and added parameter to compiler - http://blog.flexexamples.com/2008/12/21/using-a-custom-flex-configxml-file-in-flex-builder-3/) and other googled solutions. Nothing is working I just see this:
[SWF] bestPairs.swf - 3,190,645 bytes after decompression
and later on:
[Unload SWF] bestPairs.swf
I'm using iPhone4 Air simulator to test app.
Is there any way to display trace logs? It's hard to develop without them.
Any help will be appreciated,
Regards!
Unless I am missing something, you never add a Main object to your application. For the trace to occur, you have to instantiate an instance of Main. Prior to that, none of the code in that class will run
Is possible to check Internet connection, than choose view according to connection/no connection?
Thanks
Maybe the following code will be useful:
<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.TestConnectionHomeView" applicationDPI="160" creationComplete="init()">
<fx:Script>
<![CDATA[
import air.net.URLMonitor;
private var monitor:URLMonitor;
public function init():void{
monitor = new URLMonitor(new URLRequest('http://www.adobe.com'));
monitor.addEventListener(StatusEvent.STATUS, announceStatus);
monitor.start();
}
public function announceStatus(e:StatusEvent):void {
trace("Status change. Current status: " + monitor.available);
}
]]>
</fx:Script>
</s:ViewNavigatorApplication>
Please see this link Detecting HTTP connectivity for a more explanation.
I have a crash that only happens with the installed application I can't make it cvrash in the IDE(Flash Builder debug or run option)
After a long time of commenting and uncomenting code I found the problem and I am posting the code below
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:ns="generic_components.*"
creationComplete="windowedapplication1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
//import core.Logger;
import mx.controls.Alert;
import mx.events.FlexEvent;
import spark.events.TextOperationEvent;
protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
{
//Logger.init();
}
public static function humanFromCamelCase(txt:String):String{
var res:String=txt.charAt(0);
//Logger.write("camel case for "+txt);
for (var i:int=1;i<txt.length;i++)
{
// Logger.write("camel iter "+i);
var c:String=txt.charAt(i);
//Logger.write("camel char is "+c);
if(c==c.toUpperCase())
{
res=res+" "+c;
}
else
res=res+c;
}
return res;
}
protected function test_clickHandler(event:Event):void
{
Alert.show(humanFromCamelCase("CompanyId"));
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Button id="test" label="TEST" click="test_clickHandler(event)"/>
</s:WindowedApplication>
Also see a web sample here http://ploscariu.com/crash/TestWeb.html (may be not there in the future)
What is weird about this crash:
1 I have no idea what happens
2 The usual crash handler in the player does not show up
3 is not crashing in the development enviroment IDE
4 if i uncomment those Logger.write then the code works on my machine fine(it could not work on all machines), the Logger.write writes the sting in a file and is placed in another project swf (I did not included the logger code)
I a, assuming that the call to Logger.write can cause a delay or something similar
It is something wrong in my code or the player is buggy? or the compiler??
Any ideas?
Edit:
-is not the logger i use since the error happens when I am not using it like in the sample code or page, no logger the app it crashes
-i get no dialog from Flash with a crash report
This is so incredibly odd!!!! I have NO idea why this happening (yet)... but I have a workaround:
Instead of res=res+c, use res+=c:
public static function humanFromCamelCase(txt:String):String{
var res:String=txt.charAt(0);
for (var i:int=1;i<txt.length;i++)
{
var c:String=txt.charAt(i);
if(c === c.toUpperCase())
{
res += " " + c;
}
else
res += c;
}
return res;
}
I have no idea why you're having an error, however, I would replace the function with this instead:
public static function humanFromCamelCase(txt:String):String{
return txt.replace(/([A-Z])/g, ' $1').replace(/^ /, "");
}
Haven't tested it, but you get the idea. This is a much simpler and faster approach.
I also thought of another way:
public static function humanFromCamelCase(txt:String):String{
return txt.split(/(?=[A-Z])/).join(' ');
}
I have a class called S3Uploader which extends Sprite, which has a private function init, which looks sometihng like this:
private function init(signatureUrl:String,
prefixPath:String,
fileSizeLimit:Number,
queueSizeLimit:Number,
fileTypes:String,
fileTypeDescs:String,
selectMultipleFiles:Boolean,
buttonWidth:Number,
buttonHeight:Number,
buttonUpUrl:String,
buttonDownUrl:String,
buttonOverUrl:String
):void {
//do stuff
}
In my flex app, I am trying to display the sprite and call the init function when the app is loaded. my code so far is this:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
initialize="init();">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import S3Uploader;
function init() {
var s3upload:S3Uploader = new S3Uploader();
s3upload.init('/s3_uploads2.xml', '', 524288000, 100, '*.*', 'All Files', true, 100, 30, '/images/upload-button.png', '/images/upload-button.png', '/images/upload-button.png');
uploader.addChild(s3upload);
}
]]>
</fx:Script>
<s:SpriteVisualElement id="uploader" />
</s:Application>
however, on the line where i call s3upload.init, i get a 1195 error saying "1195: Attempted access of inaccessible method init through a reference with static type S3Uploader."
When i looked up this error, it seems like almost everyone getting this was trying to call a function with set or get. However, I am not doing this and i have no idea why i am getting this error. Does anyone know what I am doing wrong?
You should learn the basics of OOP. You cannot call private functions from not within function owner objects. Mark it as public.
I've got a really simple flex application, with a main file Rec.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="215" minHeight="138" width="215" height="138" backgroundAlpha="0.0">
<fx:Script>
<![CDATA[
var rec:LRec = new LRec();
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:Application>
And an AS3 class:
package
{
import mx.core.Application;
import mx.events.FlexEvent;
public class LRec extends Application
{
public function LRec()
{
trace("CONSTRUCTED");
addEventListener(FlexEvent.APPLICATION_COMPLETE, this.mainInit);
}
/**
* After the application startup is complete, debug
*/
public function mainInit(event:FlexEvent):void {
trace("COMPLETE");
}
}
}
The trace ("CONSTRUCTED") is printed, but not "COMPLETE" -- it looks like the FlexEvent.APPLICATION_COMPLETE event is never registering. Any ideas why?
Also, this is the first time I've really done this sort of programming, so if anything else looks wrong, please tell me!
I've updated your code below with some comments on where you were going wrong. If you have any other questions feel free to ask.
Test.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="215" minHeight="138" width="215" height="138" backgroundAlpha="0.0"
initialize="handle_initialize(event)"
>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
// Probably want to keep your rec object around
private var rec:LRec;
// Construct your LRec instance in the Application's inititialize state,
// rather than declaring it statically.
protected function handle_initialize(event:FlexEvent):void
{
// Construct a new LRec instance, assign it to our private variable.
this.rec = new LRec();
// The <s:Applicaiton instance we define in this mxml is the object that
// will actually dispatch the applicationComplete event, so we want to
// listen for that here and pass it on to our LRec instance's mainInit
// method when it fires.
this.addEventListener(FlexEvent.APPLICATION_COMPLETE, this.rec.mainInit);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:Application>
LRec.as
package
{
import mx.events.FlexEvent;
// Don't inherit from Application, as you've already defined your application
// in your mxml, and you should have only one Application instance per application.
public class LRec
{
public function LRec()
{
trace("CONSTRUCTED");
// Doesn't need the event listener anymore.
// Do any instantiation needed.
}
/**
* After the application startup is complete, debug
*/
public function mainInit(event:FlexEvent):void {
trace("COMPLETE");
// Do any of the work that needs to wait for the applicationComplete
// event to fire.
}
}
}
Here's a good article (though a bit dated) on the Flex Instantiation Model.