TScrollBox or TChart memory leak (FMX, C++) - firemonkey

I've been trying to find a memory leak on iOS and i'm 99% it is either in a TScrollBox or in a TChart. The action that leads to the crash is simple scrolling back and forth across the TChart. The app behaves well in Win32 and memory useage is stable.
The crash cause on iOS is EXC_RESOURCE -> myappname[5548] exceeded mem limit: ActiveHard 1400MB (fatal) per Xcode Console.
To exclude my spaghetti code as the culprit i created a simple project to reproduce the error and it crashes too. Below are snips from the Xcode Console output. I get tons of assertions, then the Received memory warning, then the iOS kernal kills my app (Project1).
default 20:28:26.180333 -0500 assertiond [Project1:7693] Activate assertion: <BKProcessAssertion: 0x12b0102c0; "com.apple.UIKit.KeyboardManagement.message" (finishTask:180s); id:…8EA7F5E94DD5>
default 20:28:26.180542 -0500 assertiond [Project1:7693] Setting jetsam priority to 10 [0x10108]
default 20:28:26.182151 -0500 assertiond [Project1:7693] Deactivate assertion: <BKProcessAssertion: 0x12b0102c0; "com.apple.UIKit.KeyboardManagement.message" (finishTask:180s); id:…8EA7F5E94DD5>
default 20:28:26.182312 -0500 assertiond [Project1:7693] Setting jetsam priority to 10 [0x10100]
default 20:28:26.183307 -0500 assertiond [Project1:7693] Remove assertion: <BKProcessAssertion: 0x12b0102c0; "com.apple.UIKit.KeyboardManagement.message" (finishTask:180s); id:…8EA7F5E94DD5>
default 20:28:32.609723 -0500 Project1 Received memory warning.
Then a short time later i see the following console message:
default 20:28:45.881914 -0500 kernel EXC_RESOURCE -> Project1[7693] exceeded mem limit: ActiveHard 1400 MB (fatal).
My crash test app is a simple Firemonkey app built in C++ Builder 10.3.2.
A) Put a TPanel on the form (Panel1).
B) Put a TScrollBox on Panel1 (ScrollBox1). Set its align to Contents.
C) Put a TLayout on ScrollBox1 (Layout1). Set its align to None. Set its width to 2100.
D) Put a TChart on Layout1. Set its height to 200, width 7300. Set its align to None.
E) Add a TToolBar to Form1 and put a TButton on it.
F) Then put this code in the TButton's click event:
Form1->Layout1->Position->X = 0;
Form1->ChartTest->Position->Y = 0;
Form1->ChartTest->Position->X = 0;
TLineSeries *series1 = new TLineSeries(Form1);
TLineSeries *series2 = new TLineSeries(Form1);
TLineSeries *series3 = new TLineSeries(Form1);
TLineSeries *series4 = new TLineSeries(Form1);
series1->Color = claBlue;
series2->Color = claRed;
series3->Color = claBlueviolet;
series4->Color = claAqua;
double x, y;
for (int i = 0; i < 1000; i++) {
x = i;
y = Random(5000);
series1->AddXY(x,y);
y = Random(5000);
series2->AddXY(x,y);
y = Random(5000);
series3->AddXY(x,y);
y = Random(5000);
series4->AddXY(x,y);
}
Form1->ChartTest->AddSeries(series1);
Form1->ChartTest->AddSeries(series2);
Form1->ChartTest->AddSeries(series3);
Form1->ChartTest->AddSeries(series4);
G) And now, with your iOS device connected to your mac and Xcode Console open, filter the Console output on "Project1" if that is what you named it. Then run the app and scroll backwards/forwards and/or up/down (also change orientation if you want back and forth). You will see tons of assertions. Eventually (takes around 2-3 minutes of this harassment to make it crash) it will eat up enough memory that it crashes.
I think the memory leak is in the TeeChart most likely, maybe in the TScrollBox?
thanks,
russ

The memory leak is in the TChart. I created another simple project with no scrollbox and i added a timer that moves the TChart up and down every 0.1 seconds. After 2-3 minutes it crashes on memory error on iOS with no user input after clicking Button1 to start things off. This crash occurs with no scrolling or any interaction - just the chart wiggling around.
Testing the app on Win32 works fine - memory is stable and not growing.
So, i'm hoping there is something obvious in how i create the chart that is the deficiency - i really don't want to abandon ship as Steema charts are so flexible. I've also posted to the Steema forum's but due to low volume there i'm posting here too.
Any ideas? Note i'm also using a licensed version of TeeChart Standard VCL/FMX released May 30, 2019 - Build 2019.27.190530. I also ran a test case where the chart is stationary (no user input and no timer event moving the chart around) and no crash. It has to do with the chart being rejiggered somehow. I tried Form1->ChartTest->AutoRepaint = false; but had no effect. The zipped test project is here: Project1a
thanks,
russ
UPDATE: The memory leak bug is present in TeeChart Standard build 2019.27.190530 but is not present in the free/lite version that comes stock with Rad Studio 10.3.2 as of now (version v2016.17.160129).

Related

How to set zoom level for MS-Edge in IE MODE browser using selenium 3.141.59 on windows 11?

I am automating a web application in ME-Edge in IE Mode on Windows 11. I have to set zoom level to 80% for same requirement for all end to end test cases. I tried with multiple given code
// To zoom out 3 times
for(int i=0; i<3; i++){
driver.findElement(By.tagName("html")).sendKeys(Keys.chord(Keys.CONTROL,Keys.SUBTRACT));
}
Also tried with JavascriptExecutor, but its working for launching page, once logged in and it goes to next page where browser zoom will be 100% again and execution stops.
JavascriptExecutor jse = (JavascriptExecutor)driver;
Thread.sleep(3000);
System.out.println("Zoom with 80%");
jse.executeScript("document.body.style.zoom='80%'");
Also, tried with press CTRL+SUBTRACT but script stops further execution.
System.setProperty("webdriver.ie.driver",
FileReaderManager.getInstance().getConfigReader().getDriverPath()
+ "\\IEDriverServer32bit.exe");
InternetExplorerOptions edgeIe11Options = new InternetExplorerOptions();
Map<String, Object> ops = (Map<String, Object>) edgeIe11Options.getCapability("se:ieOptions");
ops.put("ie.edgechromium", true);
ops.put("ie.edgepath", "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"); edgeIe11Options.introduceFlakinessByIgnoringSecurityDomains();
edgeIe11Options.ignoreZoomSettings();
edgeIe11Options.enablePersistentHovering();
edgeIe11Options.getBrowserName();
edgeIe11Options.takeFullPageScreenshot();
// edgeIe11Options.disableNativeEvents();
edgeIe11Options.requireWindowFocus();
edgeIe11Options.destructivelyEnsureCleanSession();
edgeIe11Options.setCapability("ignoreProtectedModeSettings", true);
edgeIe11Options.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.IGNORE);
driver = new InternetExplorerDriver(edgeIe11Options);
You have almost every possible means of setting the zoom level, but it usually will not cause any issue except when you perform some mouse action. Notes from Selenium docs:
The browser zoom level must be set to 100% so that the native mouse
events can be set to the correct coordinates.
So I would suggest restoring the browser zoom level to 100% when you need to perform mouse action, and zoom in/out when you actually need it, though it may sound rather complicated.

What has changed? Wake Windows and turn on monitor from Windows API

I have an old C program for displaying caller ID called YAC. Fortunately, the author Jensen Harris provided the source.
15 years ago, I modified the source to turn on the monitor if the computer was awake but the monitor was off. The code below worked well, turning on the monitor and making the caller ID message visible on the screen.
// TG - add a call to turn on the monitor if it is sleeping.....
SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
Recently the behavior has changed (presumably a Windows update changed something)
Now when a Caller ID message should be displayed, the monitor turns on (as evidenced by the LED), but the screen remains black. The monitor remains in the black-screen condition for a few seconds, then turns off again.
What additional or different call is now required to cause Windows to activate the display and show the desktop? Possibly this could be forced by sending a mouse move, but is there a better way?
EDIT:
I have implemented the following additional code to press and release ESC. I was unable to find a good example of a relative mouse move of 1 pixel, so I used an example for keyboard. I will test and see if it is effective.
INPUT inputs[2];
UINT uSent;
// reference: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_ESCAPE;
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_ESCAPE;
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
EDIT2 - I can confirm this approach does work to cause the monitor to display video, but of course has the potential for side-effects as any keyboard or mouse action would. I would still be interested in learning of a pure API function that works to fully wake the system like SC_MONITORPOWER used to.

App did not run at iPhone resolution when reviewed on iPad running iOS 10.2.3

This is my first iOS app, designed explicitly for the iPhone, not iPad, but apparently Apple won't put it on their store unless it will run on a iPad as well. I'm at a total loss as how to "fix" this. I've searched everywhere for suggestions and nothing I've tried works (including here on StackOverflow). I can run the app in the iPad simulator and get the same results as Apple does, but can't seem to find a fix. This is proving extremely frustrating, especially when one considers that this app won't run on a iPad because it needs access to a cellular network.
I'm using the latest Xamarin for Visual Studios and I'm using Visual Studios 2013. There is no mention of the iPad in Info.plist or anywhere else for that matter
Anyone have any suggestions?
R/
Prescott ....
You are receiving this from Apple because you might have indicated your app is an Universal App.
To indicate your application will only run on iPhones you need to set this in the info.Plist file if using Xamarin Studio. When using Visual Studio this is in the project properties. The option is called "Devices" make sure you select iPhone/iPod from the dropdown list.
Device selection in VS2017
I know you said you are using 2013 but this might give you an idea.
All,
Apple requires that apps run on all iOS platforms. Accordingly I had to add constraints to my storyboard to adjust the location of subviews on each screen. Because adding each constraint is tedious, I used Cirrious Fluent Layout which worked very well for me. Below is the code I used on my screen that included a imageview. This was the most complicated screen to "fix" because (apparently) the imagevies somehow changed all the screen sizes, being an iOS developer novice, I had no idea why this worked, only that it did.
First I needed to add the reference:
using Cirrious.FluentLayouts.Touch;
Code:
//This line is required to turn off all autosizing/positioning
View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
// Get the screen dimensions and the middle of the screen
// for button positioning
var barheight = this.NavigationController.NavigationBar.Bounds.Height;
// Height of the navigation bar
var height = UIScreen.MainScreen.Bounds.Height;
var width = UIScreen.MainScreen.Bounds.Width;
int middle = (int) UIScreen.MainScreen.Bounds.Width / 2;
// We cast to int to truncate float,
// int will convert implictly to float when used (Visual Studio).
var heightavailabletoimageviw = height -74 - 47 - 26 - 60;
// 74 is the height of the banner, 47 is the height of the buttons and
// 26 is the height of the title label plus a 5px gap The rest of the
// screen is available for use by the image view,
// set heightavailabletoimageviw to this value
// Had to subtract 60 because the image view still overlapped
// the buttons, no idea why. Anyone?
// Had to add a constraint to the imageview because if I didn't
// it automatically scaled to the size of the image, not good.
ThePhoto.AddConstraints(
ThePhoto.Width().EqualTo(UIScreen.MainScreen.Bounds.Width),
ThePhoto.Height().EqualTo(heightavailabletoimageviw)
);
// Had to fix the size of the imagebutton otherwise the button size
// scaled to the size of the image
btnPhoto.AddConstraints(
btnPhoto.Width().EqualTo(62f),
btnPhoto.Height().EqualTo(47f)
);
// Now we add the constraints to the viewcontroller to finish up.
View.AddConstraints(
// Can't cover the navigation bar (unless it isn't there, mine is),
// this value sets all other relative positions
Banner.AtTopOf(View, barheight),
Banner.AtRightOf(View, 0),
Banner.AtLeftOf(View, 0),
lblTitle.Below(Banner, 0),
lblTitle.WithSameWidth(Banner),
ThePhoto.Below(lblTitle, 5),
ThePhoto.WithSameWidth(lblTitle),
// I have no idea why, but I had to use negative
// values for the buttons to appear on the screen,
// otherwise they were off screen.
// If anyone could explain this, I would appreciate it.
btnUpload.AtBottomOf(View),
btnUpload.ToLeftOf(View,-60),
// Same here, had to use negative values for button to
// position correctly on the screen
btnPhoto.AtBottomOf(View),
btnPhoto.ToLeftOf(View,-(middle + 31)),
// Again, same thing.
btnMainMenu.AtBottomOf(View),
btnMainMenu.ToRightOf(View,-80)
);
This is how I solved my problem, I re-submitted the app and it now appears on the app store at: https://itunes.apple.com/us/app/oml-photo-manager/id1212622377?mt=8.
Hope this helps someone ....
R/
Prescott ...

TeeChart showing abnormal message box and accumulating memory

I am using TeeChart Pro v2013.0.1.4.131120 32bit ActiveX in an MFC application. There are 15 chart windows dynamically created on a dialog running on a UI thread and all of the charts windows get constantly updated by messages from the main thread. I am encountering the following issues:
An abnormal message box with "2." written inside constantly pops up once after the chart windows are created and updated.
Although at regular interval I am freeing the data for each chart with the following code I find that memory is continuously getting accumulated.
This is the code I'm using:
long sz = pchart_->GetSeriesCount();
for (int i = 0; i <= sz; ++i) {
pchart_->Series(i).Clear();
}
pchart_->RemoveAllSeries();
Can anyone please help/ highlight me regarding what is going wrong here?

Sprite Kit Serious FPS Issue In Full Screen Mode on OS X

I'm making a fairly complex sprite kit game. I recently added support for OS X. I get 60 fps always, regardless of how my game is scaled when the window is resized (even when resized to max screen space). However, the moment I make my App enter "Full Screen," the fps drops to 30-40 fps and stays that way? But if I take my mouse cursor and reveal the menu bar while full screen is enabled, the fps goes back up to 60 fps!
You can even test this bug by making a sprite kit game for mac in Xcode using the default template. Here are the screen shots I took of the default game template for mac.
I suggest trying it out for yourself, you don't even have to write any code if you use Apple's default sprite kit template for OS X.
Max Window (No FPS Problems: 59-60 FPS)
Full Screen Mode (FPS Drops to 30-40 FPS)
Full Screen Mode With Mouse At Top Revealing Menu Bar (Surprisingly, NO FPS Issues: 59-60 FPS)
Anyone have any idea what might be causing this problem. I don't want to release my App with full screen mode if it means users will lose performance. You would think full screen mode could better optimize drawing but apparently it's quite the opposite. I'm running this on Yosemite.
Ok, after weeks looking into this issue I have found some workarounds to this issue. Before I begin, let me start by explaining my setup. I'm using an NSViewController in a storyboard which holds an SKView. I've tested the workaround on MacBook Pro (Retina, 15-inch, Early 2013), I have no idea if the workarounds I present below will work on other Macs. I believe it should, when I get the chance I will test and see if the workarounds below work.
So before I begin, lets recap what the issue is. The issue is that making your App enter fullscreen by clicking the fullscreen button causes a massive drop in FPS. Below is how you enable the fullscreen button:
self.view.window!.collectionBehavior = .FullScreenPrimary
So then I searched around and found a different way of entering fullscreen using this code:
self.view.enterFullScreenMode(NSScreen.mainScreen()!, withOptions: nil)
But I still had a massive drop in FPS. Keep in mind, I had no fps issues when in maximized window mode or even full screen with the menu bar visible! (see pictures in question).
So then I tried a less high-level approach to going full screen. I found a guide by Apple here
Using some of the code from the guide, I managed to enter fullscreen by setting the window size to the size of the display, and positioning the window above all OS X UI. The code for this is as follows:
self.view.window!.styleMask = NSBorderlessWindowMask
self.view.window!.level = Int(CGWindowLevelForKey(Int32(kCGMainMenuWindowLevelKey))) + 1
self.view.window!.opaque = true
self.view.window!.hidesOnDeactivate = true
let size = NSScreen.mainScreen()!.frame.size
self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height), display:true)
But, sadly, same problem... The FPS just dropped just like before.
So then I thought what if I mess with the size/position of the window. So I tried moving the window down so that just the menu bar was visible as shown below. AND THIS WORKED. I no longer had a drop in fps. But obviously it's not truly fullscreen because the menu bar is visible
self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height-NSApplication.sharedApplication().mainMenu!.menuBarHeight), display:true)
In fact, as it turns out, just be adjusting the window size by 1 point fixes the drop in fps. Thus the bug must be related to an optimization (how ironic) apple does when your window size matches the screen size.
Don't believe me? Here is a quote from the link.
OS X v10.6 and later automatically optimize the performance of
screen-sized windows
So to fix the issue all we need to do is make our window size height 1 point larger which will prevent OS X from trying to optimize our window. This will cause your App to get slightly cut off on the top but 1 pixel shouldn't be noticeable at all. And in the worst case you could adjust your nodes position by 1 point to account for this.
For your convenience, listed below are the 2 workarounds. Both of these workarounds do not cause any drop in FPS. Your App should function just like it did in maximized window mode. The first workaround puts your App in fullscreen and displays the menu bar at the top. The second workaround puts your App in complete full screen with no menu bar.
Workaround 1: Fullscreen with Menu Bar
self.view.window!.styleMask = NSBorderlessWindowMask
self.view.window!.level = Int(CGWindowLevelForKey(Int32(kCGMainMenuWindowLevelKey))) + 1
self.view.window!.opaque = true
self.view.window!.hidesOnDeactivate = true
let size = NSScreen.mainScreen()!.frame.size
self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height-NSApplication.sharedApplication().mainMenu!.menuBarHeight), display:true)
Workaround 2: Fullscreen with no Menu Bar
self.view.window!.styleMask = NSBorderlessWindowMask
self.view.window!.level = Int(CGWindowLevelForKey(Int32(kCGMainMenuWindowLevelKey))) + 1
self.view.window!.opaque = true
self.view.window!.hidesOnDeactivate = true
let size = NSScreen.mainScreen()!.frame.size
NSMenu.setMenuBarVisible(false)
self.view.window!.setFrame(CGRect(x: 0, y: 0, width: size.width, height: size.height+1), display:true)
If for some reason these workarounds don't work, try messing some more with the size/position of the window. Also you may need to change the window level depending on if you have other views such as dialogues that your App should not overlap. Also please remember to file bug reports with Apple.
Additional Info About NSBorderlessWindowMask
These workarounds use an NSBorderlessWindowMask. These type of windows do not accept keyboard input when the key window changes. So if your game uses keyboard input, you should override the following. See here
class CustomWindow: NSWindow {
override var canBecomeKeyWindow: Bool {
get {
return true
}
}
override var canBecomeMainWindow: Bool {
get {
return true
}
}
}
Update: Some bad news
Tested this workaround on Mac Book Air, and it did not work unless about 100 points were subtracted (which obviously is extremely noticeable). I have no idea why. Same goes for andyvn22's solution. I also have noticed that very rarely, perhaps once every 60 launches the workarounds provided simply don't work on the Mac Book Air at all. And the only way to fix is to relaunch the App. Maybe the Max Book Air is a special case. Maybe lack of a graphics card has to do with the issue. Hopefully Apple gets the issue sorted out. I'm now torn between supporting fullscreen and not supporting fullscreen. I really want users to be able to enter fullscreen mode, but at the same time I don't want to risk users loosing half their FPS.
Based on Epic Byte's very helpful work, I found an even easier way to disable Apple's full screen "optimization". You can still use OS X's built in full screen capability; all you have to do is implement the following method in your window's delegate:
func window(window: NSWindow, willUseFullScreenContentSize proposedSize: NSSize) -> NSSize {
return NSSize(width: proposedSize.width, height: proposedSize.height - 1)
}
Unfortunately adding one pixel doesn't seem to work this way, only subtracting one, so you lose a row of screen space. Totally worth it to me, though, to continue using the built-in full screen function, especially while just waiting for Apple to fix their optimization bug.
I believe this problem occurs on all apps using OpenGL to render. MPV (video player) with the following video config has the same issues: vo=opengl hwdec=no
Cpu usage - windowed: average 42%
Cpu usage - fullscreen (native): 62%
Cpu usage - fullscreen (non-native/in app): 60%
Cpu usage - fullscreen (native with menu bar): 45%
Cpu usage - offscreen (using native full screen): 95%
This also occurs on PPSSPP with OpenGL backend except with increased GPU instead of cpu usage:
Gpu usage - windowed: average 20%
Gpu usage - fullscreen (with menu bar): 20%
Gpu usage - fullscreen (native): 35%
Gpu usage - offscreen (using native full screen): 90%
This problem however does not seem to occur when developers implement their own "Special" fullscreen. In the case of Enter the Gungeon, where cpu usage and gpu usage shows no difference between windowed and FS. Although I haven't had time to check how they've implemented fullscreen yet.
Tested on MBP Late 2015 13' on OSX 10.11.6
The slightly increased usage during fullscreen is a bit annoying as you've said and can cause framedrops, but what's worrying me the most is the near 100% usage of both CPU and GPU in openGL applications when in background. (Note: it's 90% on ppsspp no matter what it's doing, even when paused).

Resources