I have a MacOS app that creates many NSViews of differing types, some of which contain WKWebViews. The Number of WKWebViews can become fairly large (dozens or more).
The problem is that each of these WKWebViews creates several processes, as can be easily seen in Activity Monitor. When the number of processes becomes too large, the entire system essentially grinds to a halt: running apps still function slowly, but new apps can't be launched, the Finder stops working, and the system must be rebooted.
So I am looking for a way to control the number of processes started by WKWebViews.
According to Apple docs, this is managed by the processPool property of WKWebView, as they state: "The process pool associated with a web view is specified by its web view configuration. Each web view is given its own Web Content process until an implementation-defined process limit is reached; after that, web views with the same process pool end up sharing Web Content processes." (from the page at: https://developer.apple.com/documentation/webkit/wkprocesspool?language=objc).
I cannot figure out how to define that "implementation-defined process limit". When I NSLog the description of the WKWebView's configuration, I get this:
WKWebView configuration description:
>; preferences = >
I can see there's a processPool and a configuration for it (called _WKProcessPoolConfiguration), and a value called maximumProcessCount, which is set to 0. I am assuming that 0 means that the process count is unlimited, and I would like to set it to a reasonable number. But I cannot figure out how to set this value! The processPool itself has no properties, so I have no idea how to access this maximumProcessCount value.
Any help is greatly appreciated.
you can use singleton WKProcessPool and all wkwebview.configuration.processpool use that WKProcessPool singleton;
it will resolve cpu too high.
Related
As I understand the creation of processes, every process has it's own space in RAM for it's heap, data, etc, which is allocated upon its creation. Many processes can share their data and storage space in some ways. But since terminating a process would erase its allocated memory(so also its caches), I was wondering if it is possible that many (similar) processes share a cache in memory that is not allocated to any specific process, so that it can be used even when these processes are terminated and other ones are created.
This is a theoretical question from a student perspective, so I am merely interested in the general sence of an operating system, without adding more functionality to them to achieve it.
For example I think of a webserver that uses only single-threaded processes (maybe due to lack of multi-threading support), so that most of the processes created do similar jobs, like retrieving a certain page.
There are a least four ways what you describe can occur.
First, the system address space is shared by all processes. The Operating system can save data there that survives the death of a process.
Second, processes can map logical pages to the same physical page frame. The termination of one process does not cause the page frame to be deallocated to the other processes.
Third, some operating systems have support for writable shared libraries.
Fourth, memory mapped files.
There are probably others as well.
I think so, when a process is terminated the RAM clears it. However your right as things such as webpages will be stored in the Cache for when there re-called. For example -
You open Google and then go to another tab and close the open Google page, when you next go to Google it loads faster.
However, what I think your saying is if the Entire program E.G - Google Chrome or Safari - is closed, does the webpage you just had open stay in the cache? No, when the program is closed all its relative data is also terminated in order to fully close the program.
I guess this page has some info on it -
https://www.wikipedia.org/wiki/Shared_memory
As the title says, I want to associate a random bit of data (ULONG) with a running process on the local machine. I want that data persisted with the process it's associated with, not the process thats reading & writing the data. Is this possible in Win32?
Yes but it can be tricky. You can't access an arbitrary memory address of another process and you can't count on shared memory because you want to do it with an arbitrary process.
The tricky way
What you can do is to create a window (with a special and known name) inside the process you want to decorate. See the end of the post for an alternative solution without windows.
First of all you have to get a handle to the process with OpenProcess.
Allocate memory with VirtualAllocEx in the other process to hold a short method that will create a (hidden) window with a special known name.
Copy that function from your own code with WriteProcessMemory.
Execute it with CreateRemoteThread.
Now you need a way to identify and read back this memory from another process other than the one that created that. For this you simply can find the window with that known name and you have your holder for a small chunk of data.
Please note that this technique may be used to inject code in another process so some Antivirus may warn about it.
Final notes
If Address Space Randomization is disabled you may not need to inject code in the process memory, you can call CreateRemoteThread with the address of a Windows kernel function with the same parameters (for example LoadLibrary). You can't do this with native applications (not linked to kernel32.dll).
You can't inject into system processes unless you have debug privileges for your process (with AdjustTokenPrivileges).
As alternative to the fake window you may create a suspended thread with a local variable, a TLS or stack entry used as data chunk. To find this thread you have to give it a name using, for example, this (but it's seldom applicable).
The naive way
A poor man solution (but probably much more easy to implement and somehow even more robust) can be to use ADS to hide a small data file for each process you want to monitor (of course an ADS associated with its image then it's not applicable for services and rundll'ed processes unless you make it much more complicated).
Iterate all processes and for each one create an ADS with a known name (and the process ID).
Inside it you have to store the system startup time and all the data you need.
To read back that informations:
Iterate all processes and check for that ADS, read it and compare the system startup time (if they mismatch then it means you found a widow ADS and it should be deleted.
Of course you have to take care of these widows so periodically you may need to check for them. Of course you can avoid this storing ALL these small chunk of data into a well-known location, your "reader" may check them all each time, deleting files no longer associated to a running process.
I am developing a firefox add-on using XUL, and I want to measure and profile my extension memory usage.
How can I do this? and check which function is taking the most memory usage and how much memory usage my extension is adding to firefox?
You cannot measure the impact of a single function, the memory management in Firefox doesn't work at this level - it works with compartments. If your extension has its own window then you will be able to see the compartment of this window under about:memory?verbose (click "Minimize memory usage", otherwise you might see objects there that will be garbage collected anyway). If your extension's code runs in the context of the browser window then you are usually out of luck - you will not be able to distinguish it from the other scripts running there. It's the same with XPCOM components and JavaScript modules - all of them get loaded into the "[System Principal]" compartment.
What you can do to get your scripts separated from a large compartment however: use sandboxes, a sandbox always gets its own compartment. For example, in a browser window you would do something like this:
Components.utils.import("resource://gre/modules/Services.jsm");
var mySandbox = Components.utils.Sandbox(window,
{sandboxName: "myExtension/browserScript.js"});
mySandbox.window = window; // Expose window variable to scripts in the sandbox
Services.scriptloader.loadSubScript("chrome://myextension/content/browserScript.js",
mySandbox);
mySandbox.init(); // Call function init() of the script in the sandbox
As a result, a compartment called myExtension/browserScript.js will be displayed under about:memory?verbose and you will be able to see how much memory this script (along with objects it creates etc.) takes exactly. Things to keep in mind:
The script in the sandbox won't have access to the variables from "outside". You have to explicitly set these variables as properties of the sandbox (like I've done with the window variable in the example).
Compartments aren't cheap, and passing objects between compartments isn't cheap either. So creating one compartment for each function would be a bad idea because of the overheads involved.
Documentation: Sandbox, Services.jsm
Update: As of Firefox 13 things changed. There is this extension for example that will show you all the objects currently in memory. Still far from being comfortable, also getting the whole picture is non-trivial - but it gives you granularity on a level below compartments.
What is the best way to determine how many window handles an application is using? Is there a tool or a WMI performance counter that I could use?
I would like to run up an app and watch a counter of some sort and see that the number of window handles is increasing.
for (int i=0; i < 1000; i++)
{
System.Threading.Thread.Sleep(1000);
RichTextBox rt = new RichTextBox();
rt.Text = "hi";
this.Controls.Add(rt);
}
I am running the above code and watching the "Handle Count" counter on the process, and it does not seem to be increasing. Is there something I am looking at incorrectly?
Perfmon, which comes with your computer can do it. You can also add a column to your task manager processes tab (Handle Count).
Instructions for Perfmon
Add a counter (click the +)
Choose Process under Performance object
Choose Handle Count under the counter list
Choose your process from the instance list
Click Add, click Close
To get the graph in range, you have to right-click it in the list, choose properties, and then choose the right scale (.1 or .01 would probably be right)
Edit (in response to added information): I think you just proved that creating RichTextBoxes doesn't result in Handles being allocated. I don't think it really needs one until you are editing the control and it might be smart enough to do that, since allocating too many resources for a control that isn't active would make it hard to have a lot of controls on a form (think about Excel, for example).
Process Monitor is very handy in interactively monitoring all sorts of resources used by Windows processes.
Process Monitor is an advanced monitoring tool for Windows that shows real-time file system, Registry and process/thread activity.
Note - if you mean finding the information programatically, .Net provides access to all performance counters. You use the System.Diagnostics.PerformanceCounter Class like this:
PerformanceCounter PC=new PerformanceCounter();
PC.CategoryName="Process";
PC.CounterName="Handles";
PC.InstanceName="MyProc";
MessageBox.Show(PC.NextValue().ToString());
The handle count shown by taskmanager is the same as the one shown by PerfMon
ProcessExplorer tool from sysinternals can list the different type of handles + their names a process uses and you can get a good idea by browsing that list about the composition of the handles your program uses.
But I'm afraid it does not sumarize these handle type counts for you.
To view the actual handles and their types using ProcessExplorer - View - show lower pane view - handles.
You can also use some sort window spy tool which shows all the windows in the system like Microsoft spy++ or Managed Spy++ (http://msdn.microsoft.com/en-us/magazine/cc163617.aspx)
This will allow you to see if your windows are being created.
Perfmon or Task Manager cannot give you the number of WINDOW handles used by a process only the total number of handles of all types (file, thread, etc.).
The best information that I can find on the subject is this post which indicates that the window handle count for a process can be determined by enumerating all child windows of the main process window.
I'm looking for advanced strategies for dealing with User Object Handle limits when building heavy-weight windows interfaces. Please explain how you overcame or bypassed this issue using SWT or direct Windows GUI APIs. The only thing I am not interested in is strategies to optimize widget usage as I have done this extensively and it does not solve the problem, only makes it less likely.
My Situation:
I have an SWT based GUI that allows for multiple sessions within the same parent shell and within each session their are 3 separate places where a list of user generated comments are displayed. As a user opens multiple sessions and pulls data that populates those lists, the number of user object handles can increase dramatically depending on the number of comments.
My current solutions:
1. I page the comments by default thereby limiting the number of comment rows in each session, but due to management demands, i also have what is effectively a "View All" button which bypasses this completely.
2. I custom draw all non-editable information in each row. This means each row utilizes only 2 object handles.
3. I created JNI calls which query the OS for the current usage and the Max usage. With this i can give indications to users that a crash is imminent. Needless to say, they ignore this warning.
First off, are you sure the problem isn't desktop heap vs. handle count? Each handle can consume a certain amount of Windows desktop heap. One USER handle may eat a lot of space, some very little. I'm suggesting this to make sure you're not chasing user handle counts when it's really something else. (google for Microsoft's dheapmon tool, it may help)
I've read that you can alter the maxes on handles by changing keys in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\Windows\ USERProcessHandleQuota and GDIProcessHandleQuota
This could be a short term fix for users.
I'd approach this by first figuring out what 2 user handles need to be maintained for each item (like 2 for each item in a listbox?). This seems suspect. User handles are for only a few top-level Windows UI objects (Windows, menus, cursors, Window positions, icons, etc...). I don't see why your widget needs to keep 2 objects around for each item (is it an icon handle??).
If you're looking to rip the whole thing apart - this sounds like a job for a virtual-mode List-View (LVS_OWNERDATA).
You should think about using windowless controls. They are designed for precisely this situation. See "Windowless controls are not magic", by Raymond Chen
Not only top-level windows, but most native controls use one user object each. See Give Me a Handle, and I'll Show You an Object for an in-depth explanation of user- and other handle types. This also means that SWT uses at least one user handle per widget, even for a Composite.
If you truly are hitting the limit of 10000 user objects per process, and you don't have a leak, then your only option is to reduce the number of widget instances in your application. I wrote a blog article about how we did this for our application.